This is the data behind the EDITS work. It follows four steps. For Step 1 I look at uptake rates between 2010 and 2021 in three countries: US, UK and Germany. For the US, I use the PSID which tracks households between 2011- 2021 on a biannual basis. For Germany, I use SOEP which tracks households between 2010- 2021 on an annual basis, and for the UK I use Understanding Society which tracks households between 2010 - 2021 on an annual basis. All data was downloaded in September 2024 and cleaning files are on github.

8 technologies selected are :Internet Access, own a smartphone, Home has Solar, Home switched from Gas/Coal/Wood to electric (fuel switching), Home renovation/ retrofitting, EV/ Hybrid car, Commuting habit (walking, biking), digital skills/ capabilities (daily use of internet).

Note: Significant limitations on technologies surveyed. With better data, I could also do this for smart-meters, air conditioners, etc.

Step 1: Uptake Rates

This provides a snapshot for current uptake across the households assessing heterogeneity across income level.

U.S. Uptake Rates

For the US, I have information for solar ownership, EV/ hybrid ownership, smartphone ownership, internet access, and commute habit. I create an additional variable on fuel switching by looking at heating method and seeing where moved from wood, oil, gas, coal to electric heating. I also create a variable for retrofitting based on home renovations and skills based on survey responses where RP responds they use the internet daily.

Note: Smartphone ownership and digital skills questions were only added to the survey in 2015.

`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.

Clean heating is interesting in that high income households had less electric only and marginally increased over 2011 - 2021 time period, though they still did increase within decile 9 and 10. Solar panel infiltration is lower than national average at 1% with EIA estimating 4%.

U.K. Uptake Rates

For the UK, I have solar, EV/ hybrid, smartphone, internet, commute and skills. I create fuel switching in the same manner as for US, buy looking at home energy bills and looking for those households that switch from gas/coal to electric only.

Solar question is only asked in 2009, 2012, 2018, and 2021. EV is asked in 2012, 2015, 2018, and 2021. Smartphone begins in 2013. Skills starts in 2011.

`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.

Germany Uptake Rates

For Germany I have information on solar, EV, retrofitting, smartphone, internet.

EV only exists in 2015 and 2020. (note it is full EV or biodiesel, no hybrid category) Retrofitting is asked from 2010 - 2015, and 2019 Smartphone

Error in select(., -internet_new) : unused argument (-internet_new)

Combined Uptake Rates

Not all technologies in each country have the same year of start and end data. I now get data as close to 2015 start and 2021 end as possible. Look at year ranges available for uptake rates for each country and technology at decile level.

There are two outlier technologies for uptake rates. The first is Sustainable Transit in the UK. UK commute (sustainable transport) only shows commuting patterns for those who work, so potentially hides significant commuting preferences, particularly for those out of work or job seeking and is being compared against COVID so less people were commuting to work in 2021, no matter their method. The second is home renovations in Germany. If i cange the year to later, the figure does go up, but 2010 shows a renovation boom that is lost in later years.

For fun, I’m also looking at US state variation, but this is for PhD, please ignore in meeting.

Step 2: Baseline Model

In the baseline model I assume no targeted policy to change distribution (i.e. 3% for 10th decile vs 15% for 1st in 2020 with a constant growth projection to 2050). Model aims to reach exogenously government provided diffusion target for each technology (e.g.40% for housing retrofit vs 60% for EVs).

U.S. Baseline

# Load required packages
library(tidyverse)
library(nls2)

# Function to fit logistic growth model for a specific decile
forecast_logistic_growth <- function(data, tech_col, decile_val, forecast_year = 2050) {
  # Create model data for specific decile
  model_data <- tibble(
    year = data$year[data$decile == decile_val],
    adoption = data[[tech_col]][data$decile == decile_val]
  ) %>%
    arrange(year) %>%
    filter(!is.na(adoption))
  
  # Normalize years to start from 0 for better model fitting
  model_data$t <- model_data$year - min(model_data$year)
  
  # Get initial parameter estimates
  K_guess <- max(100, max(model_data$adoption) * 1.2)  # Carrying capacity
  r_guess <- 0.5  # Growth rate
  N0_guess <- model_data$adoption[1]  # Initial adoption
  
  tryCatch({
    # Fit logistic growth model using nls
    # Formula: N(t) = K / (1 + ((K - N0)/N0) * exp(-r*t))
    model <- nls(adoption ~ K / (1 + ((K - N0)/N0) * exp(-r * t)),
                 data = model_data,
                 start = list(K = K_guess, r = r_guess, N0 = N0_guess),
                 control = nls.control(maxiter = 1000))
    
    # Generate future years for prediction
    future_years <- seq(min(model_data$year), forecast_year, by = 1)
    future_t <- future_years - min(model_data$year)
    
    # Extract parameters
    params <- coef(model)
    K <- params["K"]
    r <- params["r"]
    N0 <- params["N0"]
    
    # Generate predictions
    predictions <- tibble(
      year = future_years,
      t = future_t,
      predicted_adoption = K / (1 + ((K - N0)/N0) * exp(-r * t)),
      decile = decile_val
    )
    
    list(
      predictions = predictions,
      model = model,
      parameters = params,
      data = model_data,
      K = K,
      r = r,
      N0 = N0
    )
  }, error = function(e) {
    cat("Error fitting model for decile", decile_val, ":", e$message, "\n")
    NULL
  })
}

# Function to plot growth curves by decile
plot_logistic_growth <- function(forecasts_list, tech_col) {
  # Combine all predictions
  all_predictions <- bind_rows(
    lapply(forecasts_list, function(x) x$predictions)
  )
  
  # Combine all historical data
  all_data <- bind_rows(
    lapply(forecasts_list, function(x) {
      x$data %>% mutate(decile = x$predictions$decile[1])
    })
  )
  
  # Create plot
  ggplot() +
    # Historical data points
    geom_point(data = all_data,
               aes(x = year, y = adoption, color = factor(decile)),
               alpha = 0.6, size = 2) +
    # Forecast lines
    geom_line(data = all_predictions,
              aes(x = year, y = predicted_adoption, color = factor(decile))) +
    scale_color_viridis_d(name = "Income Decile") +
    theme_minimal() +
    labs(
      title = paste("Logistic Growth Forecast by Income Decile:", 
                   gsub("_percent", "", tech_col)),
      subtitle = "Historical data and logistic growth projections to 2050",
      x = "Year",
      y = "Adoption Rate (%)"
    ) +
    scale_x_continuous(breaks = seq(2010, 2050, by = 5)) +
    ylim(0, 100) +
    theme(
      panel.grid.minor = element_blank(),
      legend.position = "right"
    )
}

# Define technologies
technologies <- c("smartphone_percent", "hybrid_percent", "solar_percent", 
                 "internet_percent", "repairs_percent", "skills_percent",
                 "fuel_switch_percent")

# Create nested list for results
forecasts_by_decile <- list()

# Fit models for each technology and decile
for(tech in technologies) {
  cat("\nProcessing", tech, "\n")
  
  # Store forecasts for each decile
  decile_forecasts <- list()
  
  for(d in 1:10) {
    cat("  Decile", d, "\n")
    decile_forecasts[[d]] <- forecast_logistic_growth(us_props, tech, d)
  }
  
  # Store and plot if we have successful fits
  if(any(!sapply(decile_forecasts, is.null))) {
    forecasts_by_decile[[tech]] <- decile_forecasts
    
    # Create and print plot
    plot <- plot_logistic_growth(decile_forecasts[!sapply(decile_forecasts, is.null)], tech)
    print(plot)
    
    # Print model parameters and predictions
    cat("\nLogistic Growth Parameters for", gsub("_percent", "", tech), ":\n")
    parameter_summary <- bind_rows(lapply(decile_forecasts[!sapply(decile_forecasts, is.null)], function(x) {
      tibble(
        decile = x$predictions$decile[1],
        carrying_capacity = round(x$K, 1),
        growth_rate = round(x$r, 3),
        initial_adoption = round(x$N0, 1),
        adoption_2030 = round(x$predictions$predicted_adoption[x$predictions$year == 2030], 1),
        adoption_2040 = round(x$predictions$predicted_adoption[x$predictions$year == 2040], 1),
        adoption_2050 = round(x$predictions$predicted_adoption[x$predictions$year == 2050], 1)
      )
    }))
    print(parameter_summary %>% arrange(decile))
  }
}
# Create historical price dataset (EIA Average Retail Electricity and Gas 2005 - 2022)
historical_prices <- tibble(
  year = 2005:2022,
  elec_price = c(9.45, 10.40, 10.65, 11.26, 11.51, 11.54, 11.72, 11.88, 12.13,
                 12.52, 12.65, 12.55, 12.89, 12.87, 13.01, 13.15, 13.72, 14.77),  # cents per kWh
  gas_price = c(13.83, 13.73, 13.08, 13.89, 12.14, 11.39, 11.03, 10.71, 10.32,
                10.97, 10.38, 10.05, 10.91, 10.50, 10.44, 10.78, 11.47, 15.95)   # dollars per thousand cubic feet
)

# Merge with US dataset
US <- US %>%
  left_join(historical_prices, by = "year")

# Print summary of the new columns
cat("Summary of added energy price columns:\n")
summary(US[c("elec_price", "gas_price")])

# Create quick visualization of price trends
ggplot(historical_prices, aes(x = year)) +
  geom_line(aes(y = elec_price, color = "Electricity"), size = 1) +
  geom_line(aes(y = gas_price, color = "Natural Gas"), size = 1) +
  theme_minimal() +
  labs(
    title = "Historical Energy Prices (2005-2022)",
    y = "Price",
    color = "Energy Type"
  ) +
  scale_color_manual(values = c("Electricity" = "blue", "Natural Gas" = "red")) +
  theme(legend.position = "bottom") +
  annotate("text", x = max(historical_prices$year), y = max(historical_prices$elec_price),
           label = "cents per kWh", hjust = 1, vjust = -0.5) +
  annotate("text", x = max(historical_prices$year), y = max(historical_prices$gas_price),
           label = "dollars per thousand cubic feet", hjust = 1, vjust = -0.5)
# Calculate energy consumption
US <- US %>%
  mutate(
    # Convert electricity expenditure to kWh
    # elec_price is in cents per kWh, so multiply by 100 to convert to dollars
    elec_consumption_kwh = (elec_a_exp / (elec_price/100)),
    
    # Convert gas expenditure to thousand cubic feet
    gas_consumption_tcf = gas_a_exp / gas_price,
    
    # Calculate consumption per room (to account for house size)
    elec_consumption_per_room = elec_consumption_kwh / hh_rooms,
    gas_consumption_per_room = gas_consumption_tcf / hh_rooms
  )

# Create summary statistics
consumption_summary <- US %>%
  group_by(year) %>%
  summarise(
    avg_elec_kwh = mean(elec_consumption_kwh, na.rm = TRUE),
    median_elec_kwh = median(elec_consumption_kwh, na.rm = TRUE),
    avg_gas_tcf = mean(gas_consumption_tcf, na.rm = TRUE),
    median_gas_tcf = median(gas_consumption_tcf, na.rm = TRUE),
    avg_elec_per_room = mean(elec_consumption_per_room, na.rm = TRUE),
    avg_gas_per_room = mean(gas_consumption_per_room, na.rm = TRUE)
  )

# Print summary statistics
print("Average Annual Energy Consumption:")
print(consumption_summary)

# Create visualization of consumption trends
ggplot(consumption_summary, aes(x = year)) +
  geom_line(aes(y = avg_elec_kwh, color = "Electricity (kWh)"), size = 1) +
  geom_line(aes(y = avg_gas_tcf * 1000, color = "Gas (cf)"), size = 1) +  # Multiply by 1000 to convert to cubic feet
  theme_minimal() +
  labs(
    title = "Average Household Energy Consumption Over Time",
    y = "Consumption",
    color = "Energy Type"
  ) +
  scale_color_manual(values = c("Electricity (kWh)" = "blue", "Gas (cf)" = "red")) +
  theme(legend.position = "bottom")

# Create boxplot of consumption by house size
ggplot(US, aes(x = factor(hh_rooms), y = elec_consumption_kwh)) +
  geom_boxplot(alpha = 0.5) +
  theme_minimal() +
  labs(
    title = "Electricity Consumption by Number of Rooms",
    x = "Number of Rooms",
    y = "Annual Electricity Consumption (kWh)"
  ) +
  theme(legend.position = "none")

# Basic sanity checks (print ranges to check for unreasonable values)
cat("\nConsumption Ranges (removing outliers):\n")
consumption_ranges <- US %>%
  summarise(
    elec_kwh_min = quantile(elec_consumption_kwh, 0.05, na.rm = TRUE),
    elec_kwh_max = quantile(elec_consumption_kwh, 0.95, na.rm = TRUE),
    gas_tcf_min = quantile(gas_consumption_tcf, 0.05, na.rm = TRUE),
    gas_tcf_max = quantile(gas_consumption_tcf, 0.95, na.rm = TRUE)
  )
print(consumption_ranges)

# First, generate forecasts for each technology and decile
forecast_logistic_growth <- function(data, tech_col, decile_val, forecast_year = 2050) {
  # Create model data for specific decile
  model_data <- tibble(
    year = data$year[data$decile == decile_val],
    adoption = data[[tech_col]][data$decile == decile_val]
  ) %>%
    arrange(year) %>%
    filter(!is.na(adoption))
  
  # Normalize years to start from 0 for better model fitting
  model_data$t <- model_data$year - min(model_data$year)
  
  tryCatch({
    # Get initial parameter estimates
    K_guess <- max(100, max(model_data$adoption) * 1.2)  # Carrying capacity
    r_guess <- 0.5  # Growth rate
    N0_guess <- model_data$adoption[1]  # Initial adoption
    
    # Fit logistic growth model using nls
    model <- nls(adoption ~ K / (1 + ((K - N0)/N0) * exp(-r * t)),
                 data = model_data,
                 start = list(K = K_guess, r = r_guess, N0 = N0_guess),
                 control = nls.control(maxiter = 1000))
    
    # Generate future years for prediction
    future_years <- seq(min(model_data$year), forecast_year, by = 1)
    future_t <- future_years - min(model_data$year)
    
    # Extract parameters
    params <- coef(model)
    K <- params["K"]
    r <- params["r"]
    N0 <- params["N0"]
    
    # Generate predictions
    predictions <- tibble(
      year = future_years,
      t = future_t,
      predicted_adoption = K / (1 + ((K - N0)/N0) * exp(-r * t)),
      decile = decile_val
    )
    
    return(list(
      predictions = predictions,
      model = model,
      parameters = params,
      data = model_data,
      K = K,
      r = r,
      N0 = N0
    ))
  }, error = function(e) {
    cat("Error fitting model for decile", decile_val, ":", e$message, "\n")
    return(NULL)
  })
}

# Generate forecasts
technologies <- c("hybrid_prop", "solar_prop", "fuel_switch_prop")
forecasts_by_decile <- list()

for(tech in technologies) {
  cat("\nGenerating forecasts for", tech, "\n")
  tech_forecasts <- list()
  
  for(d in 1:10) {
    cat("  Processing decile", d, "\n")
    tech_forecasts[[d]] <- forecast_logistic_growth(us_props, tech, d)
  }
  
  forecasts_by_decile[[tech]] <- tech_forecasts
}

# Now calculate energy impacts
# Get current adoption rates
max_year <- max(us_props$year)
current_rates <- data.frame(
  decile = us_props$decile[us_props$year == max_year],
  current_hybrid = us_props$hybrid_prop[us_props$year == max_year],
  current_solar = us_props$solar_prop[us_props$year == max_year],
  current_fuel_switch = us_props$fuel_switch_prop[us_props$year == max_year]
)

# Calculate baseline consumption
baseline_consumption <- US %>%
  group_by(decile) %>%
  summarise(
    avg_energy_with_hybrid = mean(elec_consumption_kwh[hybrid == 1], na.rm = TRUE),
    avg_energy_no_hybrid = mean(elec_consumption_kwh[hybrid == 0], na.rm = TRUE),
    hybrid_impact = avg_energy_with_hybrid - avg_energy_no_hybrid,
    
    avg_energy_with_solar = mean(elec_consumption_kwh[heat_method == 6], na.rm = TRUE),
    avg_energy_no_solar = mean(elec_consumption_kwh[heat_method != 6], na.rm = TRUE),
    solar_impact = avg_energy_with_solar - avg_energy_no_solar,
    
    avg_energy_with_elec_heat = mean(elec_consumption_kwh[heat_method == 2], na.rm = TRUE),
    avg_energy_no_elec_heat = mean(elec_consumption_kwh[heat_method != 2], na.rm = TRUE),
    elec_heat_impact = avg_energy_with_elec_heat - avg_energy_no_elec_heat
  )

# Function to calculate energy impact
calculate_energy_impact <- function(current_adoption, future_adoption, energy_impact, households = 1000) {
  additional_adopters = (future_adoption - current_adoption) * households / 100
  total_impact = additional_adopters * energy_impact
  return(total_impact)
}

# Calculate impacts
tech_impacts <- list()
impact_counter <- 0

for(tech in technologies) {
  cat("\nProcessing impacts for", tech, "\n")
  
  for(d in 1:10) {
    cat("  Processing decile", d, "\n")
    
    if(!is.null(forecasts_by_decile[[tech]][[d]])) {
      forecast <- forecasts_by_decile[[tech]][[d]]
      current <- current_rates[current_rates$decile == d, ]
      baseline <- baseline_consumption[baseline_consumption$decile == d, ]
      
      impact_counter <- impact_counter + 1
      tech_impacts[[impact_counter]] <- data.frame(
        technology = gsub("_prop", "", tech),
        decile = d,
        additional_energy_2030 = calculate_energy_impact(
          current[[paste0("current_", gsub("_prop", "", tech))]], 
          forecast$predictions$predicted_adoption[forecast$predictions$year == 2030],
          switch(tech,
                "hybrid_prop" = baseline$hybrid_impact,
                "solar_prop" = baseline$solar_impact,
                "fuel_switch_prop" = baseline$elec_heat_impact)
        ),
        additional_energy_2040 = calculate_energy_impact(
          current[[paste0("current_", gsub("_prop", "", tech))]], 
          forecast$predictions$predicted_adoption[forecast$predictions$year == 2040],
          switch(tech,
                "hybrid_prop" = baseline$hybrid_impact,
                "solar_prop" = baseline$solar_impact,
                "fuel_switch_prop" = baseline$elec_heat_impact)
        ),
        additional_energy_2050 = calculate_energy_impact(
          current[[paste0("current_", gsub("_prop", "", tech))]], 
          forecast$predictions$predicted_adoption[forecast$predictions$year == 2050],
          switch(tech,
                "hybrid_prop" = baseline$hybrid_impact,
                "solar_prop" = baseline$solar_impact,
                "fuel_switch_prop" = baseline$elec_heat_impact)
        )
      )
    }
  }
}

# Combine results if we have any
if(length(tech_impacts) > 0) {
  tech_impacts_df <- do.call(rbind, tech_impacts)
  
  # Create visualization
  ggplot(tech_impacts_df %>% 
           pivot_longer(cols = starts_with("additional_energy"),
                       names_to = "year",
                       values_to = "energy_impact") %>%
           mutate(year = as.numeric(gsub("additional_energy_", "", year))), 
         aes(x = factor(decile), y = energy_impact, fill = technology)) +
    geom_col(position = "dodge") +
    facet_wrap(~year) +
    theme_minimal() +
    labs(
      title = "Projected Additional Energy Demand from Technology Adoption",
      subtitle = "By income decile and technology type",
      x = "Income Decile",
      y = "Additional Annual Energy Consumption (kWh)",
      fill = "Technology"
    ) +
    theme(legend.position = "bottom")
  
  # Print summary statistics
  cat("\nSummary of Additional Energy Demand (kWh):\n")
  print(tech_impacts_df %>%
          group_by(technology) %>%
          summarise(
            total_2030 = sum(additional_energy_2030, na.rm = TRUE),
            total_2040 = sum(additional_energy_2040, na.rm = TRUE),
            total_2050 = sum(additional_energy_2050, na.rm = TRUE)
          ))
}
LS0tCnRpdGxlOiAiRWRpdHMgTm90ZWJvb2siCmF1dGhvcjogIkNhc3NhbmRyYSBFdHRlciIKZGF0ZTogIjIwMjQtMTEtMTUiCm91dHB1dDogaHRtbF9kb2N1bWVudAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKVGhpcyBpcyB0aGUgZGF0YSBiZWhpbmQgdGhlIEVESVRTIHdvcmsuIEl0IGZvbGxvd3MgZm91ciBzdGVwcy4gRm9yIFN0ZXAgMSBJIGxvb2sgYXQgdXB0YWtlIHJhdGVzIGJldHdlZW4gMjAxMCBhbmQgMjAyMSBpbiB0aHJlZSBjb3VudHJpZXM6IFVTLCBVSyBhbmQgR2VybWFueS4gRm9yIHRoZSBVUywgSSB1c2UgdGhlIFBTSUQgd2hpY2ggdHJhY2tzIGhvdXNlaG9sZHMgYmV0d2VlbiAyMDExLSAyMDIxIG9uIGEgYmlhbm51YWwgYmFzaXMuIEZvciBHZXJtYW55LCBJIHVzZSBTT0VQIHdoaWNoIHRyYWNrcyBob3VzZWhvbGRzIGJldHdlZW4gMjAxMC0gMjAyMSBvbiBhbiBhbm51YWwgYmFzaXMsIGFuZCBmb3IgdGhlIFVLIEkgdXNlIFVuZGVyc3RhbmRpbmcgU29jaWV0eSB3aGljaCB0cmFja3MgaG91c2Vob2xkcyBiZXR3ZWVuIDIwMTAgLSAyMDIxIG9uIGFuIGFubnVhbCBiYXNpcy4gQWxsIGRhdGEgd2FzIGRvd25sb2FkZWQgaW4gU2VwdGVtYmVyIDIwMjQgYW5kIGNsZWFuaW5nIGZpbGVzIGFyZSBvbiBnaXRodWIuCgo4IHRlY2hub2xvZ2llcyBzZWxlY3RlZCBhcmUgOkludGVybmV0IEFjY2Vzcywgb3duIGEgc21hcnRwaG9uZSwgSG9tZSBoYXMgU29sYXIsIEhvbWUgc3dpdGNoZWQgZnJvbSBHYXMvQ29hbC9Xb29kIHRvIGVsZWN0cmljIChmdWVsIHN3aXRjaGluZyksIEhvbWUgcmVub3ZhdGlvbi8gcmV0cm9maXR0aW5nLCBFVi8gSHlicmlkIGNhciwgQ29tbXV0aW5nIGhhYml0ICh3YWxraW5nLCBiaWtpbmcpLCBkaWdpdGFsIHNraWxscy8gY2FwYWJpbGl0aWVzIChkYWlseSB1c2Ugb2YgaW50ZXJuZXQpLgoKTm90ZTogU2lnbmlmaWNhbnQgbGltaXRhdGlvbnMgb24gdGVjaG5vbG9naWVzIHN1cnZleWVkLiBXaXRoIGJldHRlciBkYXRhLCBJIGNvdWxkIGFsc28gZG8gdGhpcyBmb3Igc21hcnQtbWV0ZXJzLCBhaXIgY29uZGl0aW9uZXJzLCBldGMuCgpgYGB7ciBsaWJyYXJpZXMsZWNobz1GQUxTRX0KbGlicmFyeShEaWFncmFtbWVSKQpsaWJyYXJ5KHBzaWRyZWFkKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoc3VydmV5KQpsaWJyYXJ5KHByaWNlUikKbGlicmFyeShyZWFkcikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobmxzMikKbGlicmFyeShkcmMpCmxpYnJhcnkoZm9yZWNhc3QpCmxpYnJhcnkobmxzMikKCmBgYAoKYGBge3IgbG9hZCBVUywgaW5jbHVkZT1GQUxTRX0KIyBVUyBEYXRhIAoKcHNpZF92YXJsaXN0ID0gYygKICAgICAgICAiRkFNSURfNjggfHwgWzA1XUVSMjUwMDkgWzA3XUVSMzYwMDkgWzA5XUVSNDIwMDkgWzExXUVSNDczMDkgWzEzXUVSNTMwMDkgWzE1XUVSNjAwMDkgWzE3XUVSNjYwMDkgWzE5XUVSNzIwMDkgWzIxXUVSNzgwMDkiLAogICAgICAgICAgICAgICJudW1fY2hpbGQgfHwgWzA1XUVSMjUwMjAgWzA3XUVSMzYwMjAgWzA5XUVSNDIwMjAgWzExXUVSNDczMjAgWzEzXUVSNTMwMjAgWzE1XUVSNjAwMjEgWzE3XUVSNjYwMjEgWzE5XUVSNzIwMjEgWzIxXUVSNzgwMjEiLCAKICAgICAgICAgICAgICAiaGhfc3RhdGUgfHwgWzA1XUVSMjUwMDQgWzA3XUVSMzYwMDQgWzA5XUVSNDIwMDQgWzExXUVSNDczMDQgWzEzXUVSNTMwMDQgWzE1XUVSNjAwMDQgWzE3XUVSNjYwMDQgWzE5XUVSNzIwMDQgWzIxXUVSNzgwMDQiLAogICAgICAgICJoaF9zaXplIHx8IFswNV1FUjI1MDE2IFswN11FUjM2MDE2IFswOV1FUjQyMDE2IFsxMV1FUjQ3MzE2IFsxM11FUjUzMDE2ICAgICAgICAgWzE1XUVSNjAwMTYgWzE3XUVSNjYwMTYgWzE5XUVSNzIwMTYgWzIxXUVSNzgwMTYiLCAKICAgICAgICAgImhoX3Jvb21zIHx8IFswNV1FUjI1MDI3IFswN11FUjM2MDI3IFswOV1FUjQyMDI4IFsxMV1FUjQ3MzI4IFsxM11FUjUzMDI4IFsxNV1FUjYwMDI5IFsxN11FUjY2MDI5IFsxOV1FUjcyMDI5IFsyMV1FUjc4MDMwIiwgCiAgICAgICAgImhoX3R5cGUgfHwgWzA1XUVSMjUwMjQgWzA3XUVSMzYwMjQgWzA5XUVSNDIwMjUgWzExXUVSNDczMjUgWzEzXUVSNTMwMjUgWzE1XUVSNjAwMjYgWzE3XUVSNjYwMjYgWzE5XUVSNzIwMjYgWzIxXUVSNzgwMjciLCAKICAgICAgICAiZ292dF9ydF9hbGwgfHwgWzA1XUVSMjUwNzQgWzA3XUVSMzYwNzYgWzA5XUVSNDIwOTEgWzExXUVSNDczOTkgWzEzXUVSNTMwOTkgWzE1XUVSNjAxMDAgWzE3XUVSNjYxMDIgWzE5XUVSNzIxMDIgWzIxXUVSNzgxMDMiLCAKICAgICAgICAiZ292dF9ydF9wYXJ0IHx8IFswNV1FUjI1MDY5IFswN11FUjM2MDcxIFswOV1FUjQyMDg2IFsxMV1FUjQ3Mzk0IFsxM11FUjUzMDk0IFsxNV1FUjYwMDk1IFsxN11FUjY2MDk3IFsxOV1FUjcyMDk3IFsyMV1FUjc4MDk4IiwKICAgICAgICAiaGhfb3duIHx8IFswNV1FUjI1MDI4IFswN11FUjM2MDI4IFswOV1FUjQyMDI5IFsxMV1FUjQ3MzI5IFsxM11FUjUzMDI5IFsxNV1FUjYwMDMwIFsxN11FUjY2MDMwIFsxOV1FUjcyMDMwIFsyMV1FUjc4MDMxIiwgCiAgICAgICAgImhoX3ZhbHVlIHx8IFswNV1FUjI1MDI5IFswN11FUjM2MDI5IFswOV1FUjQyMDMwIFsxMV1FUjQ3MzMwIFsxM11FUjUzMDMwIFsxNV1FUjYwMDMxIFsxN11FUjY2MDMxIFsxOV1FUjcyMDMxIFsyMV1FUjc4MDMyIiwgCiAgICAgICAgImhoX2FfdXRpbCB8fCBbMDVdRVIyODAzN0IxIFswN11FUjQxMDI3QjEgWzA5XUVSNDY5NzFCMSBbMTFdRVI1MjM5NUIxIFsxM11FUjU4MjEyQjEgWzE1XUVSNjU0MTkgWzE3XUVSNzE0OTcgWzE5XUVSNzc1MzEgWzIxXUVSODE4NTgiLCAKICAgICAgICAiZ2FzX2V4cCB8fCBbMDVdRVIyNTA4MCBbMDddRVIzNjA4MyBbMDldRVI0MjExMiBbMTFdRVI0NzQxNSBbMTNdRVI1MzExNSBbMTVdRVI2MDExMCBbMTddRVI2NjExMSBbMTldRVI3MjExMSBbMjFdRVI3ODExMyIsIAogICAgICAgICJnYXNfcGVyX2V4cCB8fCBbMDVdRVIyNTA4MSBbMDddRVIzNjA4NCBbMDldRVI0MjExMyBbMTFdRVI0NzQxNiBbMTNdRVI1MzExNiBbMTVdRVI2MDExMSBbMTddRVI2NjExMiBbMTldRVI3MjExMiBbMjFdRVI3ODExNCIsIAogICAgICAgICJlbGVjX2V4cCB8fCBbMDVdRVIyNTA4MiBbMDddRVIzNjA4NSBbMDldRVI0MjExNCBbMTFdRVI0NzQxNyBbMTNdRVI1MzExNyBbMTVdRVI2MDExMiBbMTddRVI2NjExMyBbMTldRVI3MjExMyBbMjFdRVI3ODExNSIsIAogICAgICAgICJlbGVjX3Blcl9leHAgfHwgWzA1XUVSMjUwODMgWzA3XUVSMzYwODYgWzA5XUVSNDIxMTUgWzExXUVSNDc0MTggWzEzXUVSNTMxMTggWzE1XUVSNjAxMTMgWzE3XUVSNjYxMTQgWzE5XUVSNzIxMTQgWzIxXUVSNzgxMTYiLCAKICAgICAgICAiaGVhdF9tZXRob2QgfHwgWzA1XUVSMjUwNzcgWzA3XUVSMzYwNzkgWzA5XUVSNDIxMDggWzExXUVSNDc0MjkgWzEzXUVSNTMxMjkgWzE1XUVSNjAxMjQgWzE3XUVSNjYxMjUgWzE5XUVSNzIxMjUgWzIxXUVSNzgxMjciLCAKICAgICAgICAiaGVhdF9tZXRob2RfMiB8fCBbMDVdRVIyNTA3OCBbMDddRVIzNjA4MCBbMDldRVI0MjEwOSBbMTFdRVI0NzQzMCBbMTNdRVI1MzEzMCBbMTVdRVI2MDEyNSBbMTddRVI2NjEyNiBbMTldRVI3MjEyNiBbMjFdRVI3ODEyOCIsIAogICAgICAgICJoZWF0X21ldGhvZF8zIHx8IFswNV1FUjI1MDc5IFswN11FUjM2MDgxIFswOV1FUjQyMTEwIFsxMV1FUjQ3NDMxIFsxM11FUjUzMTMxIFsxNV1FUjYwMTI2IFsxN11FUjY2MTI3IFsxOV1FUjcyMTI3IFsyMV1FUjc4MTI5IiwKICAgICAgICAiZ292dF9oZWF0X2Fzc2l0YW5jZSB8fCBbMDVdRVIyNTA5MyBbMDddRVIzNjA5OCBbMDldRVI0MjEyNyBbMTFdRVI0NzQzMyBbMTNdRVI1MzEzMyBbMTVdRVI2MDEyOCBbMTddRVI2NjEyOSBbMTldRVI3MjEyOSBbMjFdRVI3ODEzMSIsIAogICAgICAgICJycF9ldGggfHwgWzA1XUVSMjczOTggWzA3XUVSNDA1NzAgWzA5XUVSNDY1NDggWzExXUVSNTE5MDkgWzEzXUVSNTc2NjQgWzE1XUVSNjQ4MTYgWzE3XUVSNzA4ODggWzE5XUVSNzY5MDMgWzIxXUVSODExNTAiLCAjIG5hdGlvbmFsaXR5IG9mIHJlZmVyZW5jZSBwZXJzb24KICAgICAgICAiaGhfaW5jb21lIHx8IFswNV1FUjI4MDM3IFswN11FUjQxMDI3IFswOV1FUjQ2OTM1IFsxMV1FUjUyMzQzIFsxM11FUjU4MTUyIFsxNV1FUjY1MzQ5IFsxN11FUjcxNDI2IFsxOV1FUjc3NDQ4IFsyMV1FUjgxNzc1IiwgCiAgICAgICAgInJlZl93YWdlIHx8IFswNV1FUjI1OTEwIFswN11FUjM2OTI4IFswOV1FUjQyOTE5IFsxMV1FUjQ4MjQxIFsxM11FUjUzOTM1IFsxNV1FUjYwOTk0IFsxN11FUjY3MDQ2IFsxOV1FUjczMDY5IFsyMV1FUjc5MTQ2IiwgCiAgICAgICAgInNwb3VzZV93YWdlIHx8IDA1XUVSMjYyODEgWzA3XUVSMzcyOTkgWzA5XUVSNDMyOTAgWzExXUVSNDg2MTUgWzEzXUVSNTQzMDkgWzE1XUVSNjEzNDkgWzE3XUVSNjc0MDEgWzE5XUVSNzM0MjQgWzIxXUVSNzk1MjYiLCAKICAgICAgICAicmVmX3dlbGZhcmUgfHwgWzA1XUVSMjc5MTMgWzA3XUVSNDA5MDMgWzA5XUVSNDY4MTEgWzExXUVSNTIyMTkgWzEzXUVSNTgwMjAgWzE1XUVSNjUyMDAgWzE3XUVSNzEyNzcgWzE5XUVSNzcyOTkgWzIxXUVSODE2MjYiLCAKICAgICAgICAic3BvdXNlX3dlbGZhcmUgfHwgWzA1XUVSMjc5ODYgWzA3XUVSNDA5NzYgWzA5XUVSNDY4ODQgWzExXUVSNTIyOTIgWzEzXUVSNTgwOTUgWzE1XUVSNjUyODggWzE3XUVSNzEzNjUgWzE5XUVSNzczODcgWzIxXUVSODE3MTQiLCAKICAgICAgICAib3RoZXJfd2VsZmFyZSB8fCBbMDVdRVIyODAxNCBbMDddRVI0MTAwNCBbMDldRVI0NjkxMiBbMTFdRVI1MjMyMCBbMTNdRVI1ODEyOSBbMTVdRVI2NTMyNiBbMTddRVI3MTQwMyBbMTldRVI3NzQyNSBbMjFdRVI4MTc1MiIsIAogICAgICAgICJob3VzaW5nX2V4cCB8fCBbMDVdRVIyODAzN0E1IFswN11FUjQxMDI3QTUgWzA5XUVSNDY5NzFBNSBbMTFdRVI1MjM5NUE1IFsxM11FUjU4MjEyQTUgWzE1XUVSNjU0MTQgWzE3XUVSNzE0OTEgWzE5XUVSNzc1MjAgWzIxXUVSODE4NDciLCAKICAgICAgICAibW9ydGFnZV9leHAgfHwgWzA1XUVSMjgwMzdBNiBbMDddRVI0MTAyN0E2IFswOV1FUjQ2OTcxQTYgWzExXUVSNTIzOTVBNiBbMTNdRVI1ODIxMkE2IFsxNV1FUjY1NDE1IFsxN11FUjcxNDkyIFsxOV1FUjc3NTIxIFsyMV1FUjgxODQ4IiwKICAgICAgICAicmVudF9leHAgfHwgWzA1XUVSMjgwMzdBNyBbMDddRVI0MTAyN0E3IFswOV1FUjQ2OTcxQTcgWzExXUVSNTIzOTVBNyBbMTNdRVI1ODIxMkE3IFsxNV1FUjY1NDE2IFsxN11FUjcxNDk0IFsxOV1FUjc3NTI1IFsyMV1FUjgxODUyIiwgCiAgICAgICAgImdhc19hX2V4cCB8fCBbMDVdRVIyODAzN0IyIFswN11FUjQxMDI3QjIgWzA5XUVSNDY5NzFCMiBbMTFdRVI1MjM5NUIyIFsxM11FUjU4MjEyQjIgWzE1XUVSNjU0MjAgWzE3XUVSNzE0OTggWzE5XUVSNzc1MzMgWzIxXUVSODE4NjAiLCAKICAgICAgICAiZWxlY19hX2V4cCB8fCBbMDVdRVIyODAzN0IzIFswN11FUjQxMDI3QjMgWzA5XUVSNDY5NzFCMyBbMTFdRVI1MjM5NUIzIFsxM11FUjU4MjEyQjMgWzE1XUVSNjU0MjEgWzE3XUVSNzE0OTkgWzE5XUVSNzc1MzQgWzIxXUVSODE4NjEiLCAKICAgICAgICAicGV0cm9sX2FfZXhwIHx8IFswNV1FUjI4MDM3QzUgWzA3XUVSNDEwMjdDNSBbMDldRVI0Njk3MUM1IFsxMV1FUjUyMzk1QzUgWzEzXUVSNTgyMTJDNSBbMTVdRVI2NTQzMiBbMTddRVI3MTUxMCBbMTldRVI3NzU1MiBbMjFdRVI4MTg3OSIsIAogICAgICAgICJzbWFydHBob25lIHx8IFsxNV1FUjYwMTM1IFsxN11FUjY2MTM2IFsxOV1FUjcyMTM2IFsyMV1FUjc4MTM4IiwKICAgICAgICAiY2VsbHBob25lIHx8IFsxNV1FUjYwMTM5IFsxN11FUjY2MTQwIFsxOV1FUjcyMTQwIFsyMV1FUjc4MTQyIiwKICAgICAgICAiY29tcHV0ZXIgfHwgWzA1XUVSMjUwOTQgWzA3XUVSMzYwOTkgWzA5XUVSNDIxMjggWzExXUVSNDc0MzQgWzEzXUVSNTMxMzQgWzE1XUVSNjAxMzEgWzE3XUVSNjYxMzIgWzE5XUVSNzIxMzIgWzIxXUVSNzgxMzQiLCAKICAgICAgICAiY2FyIHx8IFswNV1FUjI1NzA4IFswN11FUjM2NzI2IFswOV1FUjQyNzMyIFsxMV1FUjQ4MDQ4IFsxM11FUjUzNzQ1IFsxNV1FUjYwODA0IFsxN11FUjY2ODUyIFsxOV1FUjcyODU2IFsyMV1FUjc4OTMzIiwgCiAgICAgICAgImh5YnJpZCB8fCBbMTFdRVI0ODA1NSBbMTNdRVI1Mzc1MiBbMTVdRVI2MDgxMSBbMTddRVI2Njg1OSBbMTldRVI3Mjg2MyBbMjFdRVI3ODk0MCIsCiAgICAgICAgImh5YnJpZF8yIHx8IFsxMV1FUjQ4MDc5IFsxM11FUjUzNzc1IFsxNV1FUjYwODM0IFsxN11FUjY2ODgyIFsxOV1FUjcyODg2IFsyMV1FUjc4OTYzIiwKICAgICAgICAiaHlicmlkXzMgfHwgWzExXUVSNDgxMDQgWzEzXUVSNTM3OTkgWzE1XUVSNjA4NTggWzE3XUVSNjY5MDYgWzE5XUVSNzI5MTAgWzIxXUVSNzg5ODciLCAKICAgICAgICAiaGhfcmVwYWlyIHx8IFswNV1FUjI1ODA4IFswN11FUjM2ODI2IFswOV1FUjQyODE3IFsxMV1FUjQ4MTM5IFsxM11FUjUzODMzIFsxNV1FUjYwODkyIFsxN11FUjY2OTQ0IFsxOV1FUjcyOTQ4IFsyMV1FUjc5MDI1IiwKICAgICAgICAiaW50ZXJuZXQgfHwgWzE1XUVSNjAxMzIgWzE3XUVSNjYxMzMgWzE5XUVSNzIxMzMgWzIxXUVSNzgxMzUiLCAKICAgICAgICAid2VpZ2h0IHx8IFswNV1FUjI4MDc4IFswN11FUjQxMDY5IFswOV1FUjQ3MDEyIFsxMV1FUjUyNDM2IFsxM11FUjU4MjU3IFsxNV1FUjY1NDkyIFsxN11FUjcxNTcwIFsxOV1FUjc3NjMxIFsyMV1FUjgxOTU4IgogICAgICAgKSAKCnN0cl9kZiA8LSBwc2lkX3N0cih2YXJsaXN0ID0gcHNpZF92YXJsaXN0LCB0eXBlID0gInNlcGFyYXRlZCIpCgppbnB1dF9kaXJlY3RvcnkgPC0gIi9Vc2Vycy9jYXNzYW5kcmFldHRlci13ZW56ZWwvRG9jdW1lbnRzL0dpdEh1Yi9QaEQvRGF0YS9QU0lEL1BhY2thZ2VkIgpvdXRwdXRfZGlyZWN0b3J5IDwtICIvVXNlcnMvY2Fzc2FuZHJhZXR0ZXItd2VuemVsL0RvY3VtZW50cy9HaXRIdWIvUGhEL0RhdGEvUFNJRC9yZGEiCgpwc2lkX3VuemlwKGluZGlyID0gaW5wdXRfZGlyZWN0b3J5LCAKICAgICAgICAgICBleGRpciA9IG91dHB1dF9kaXJlY3RvcnksIAogICAgICAgICAgIHppcHBlZCA9IFRSVUUsIAogICAgICAgICAgIHR5cGUgPSAicGFja2FnZSIsIAogICAgICAgICAgIGZpbGVuYW1lID0gTkEpCiMjRml4IFBTSUQgUmVhZCBmdW5jdGlvbiAKcHNpZF9yZWFkX2ZpeGVkIDwtIGZ1bmN0aW9uIChpbmRpciwgc3RyX2RmLCBpZHZhcnMgPSBOQSwgdHlwZSwgZmlsZW5hbWUgPSBOQSkKewogIHllYXIgPC0gRVIzMDAwMSA8LSBFUjMwMDAyIDwtIGZhbWZpZCA8LSBpbmRmaWQgPC0gd2x0aGlkIDwtIE5VTEwKICB5ZWFyX3RvcmVhZCA8LSBzdHJfZGYkeWVhcgogIHZhcmxpc3RfdG9yZWFkIDwtIHVubmFtZSh1bmxpc3Qoc3RyX2RmWywgYygyOm5jb2woc3RyX2RmKSldKSkKICB2YXJsaXN0X3RvcmVhZCA8LSB2YXJsaXN0X3RvcmVhZFshaXMubmEodmFybGlzdF90b3JlYWQpXQogIHRlbXBfZW52IDwtIG5ldy5lbnYoKQogIHRlbXBfZW52JGtleV90YiA8LSBkcGx5cjo6ZmlsdGVyKHBzaWRfc3RyKHZhcmxpc3QgPSBjKCJ4c3FuciB8fCBcdFs2OV1FUjMwMDIxIFs3MF1FUjMwMDQ0IFs3MV1FUjMwMDY4IFs3Ml1FUjMwMDkyIFs3M11FUjMwMTE4IFs3NF1FUjMwMTM5IFs3NV1FUjMwMTYxIFs3Nl1FUjMwMTg5IFs3N11FUjMwMjE4IFs3OF1FUjMwMjQ3IFs3OV1FUjMwMjg0IFs4MF1FUjMwMzE0IFs4MV1FUjMwMzQ0IFs4Ml1FUjMwMzc0IFs4M11FUjMwNDAwIFs4NF1FUjMwNDMwIFs4NV1FUjMwNDY0IFs4Nl1FUjMwNDk5IFs4N11FUjMwNTM2IFs4OF1FUjMwNTcxIFs4OV1FUjMwNjA3IFs5MF1FUjMwNjQzIFs5MV1FUjMwNjkwIFs5Ml1FUjMwNzM0IFs5M11FUjMwODA3IFs5NF1FUjMzMTAyIFs5NV1FUjMzMjAyIFs5Nl1FUjMzMzAyIFs5N11FUjMzNDAyIFs5OV1FUjMzNTAyIFswMV1FUjMzNjAyIFswM11FUjMzNzAyIFswNV1FUjMzODAyIFswN11FUjMzOTAyIFswOV1FUjM0MDAyIFsxMV1FUjM0MTAyIFsxM11FUjM0MjAyIFsxNV1FUjM0MzAyIFsxN11FUjM0NTAyIFsxOV1FUjM0NzAyIFsyMV1FUjM0OTAyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVsMmhoIHx8IFs2OF1FUjMwMDAzIFs2OV1FUjMwMDIyIFs3MF1FUjMwMDQ1IFs3MV1FUjMwMDY5IFs3Ml1FUjMwMDkzIFs3M11FUjMwMTE5IFs3NF1FUjMwMTQwIFs3NV1FUjMwMTYyIFs3Nl1FUjMwMTkwIFs3N11FUjMwMjE5IFs3OF1FUjMwMjQ4IFs3OV1FUjMwMjg1IFs4MF1FUjMwMzE1IFs4MV1FUjMwMzQ1IFs4Ml1FUjMwMzc1IFs4M11FUjMwNDAxIFs4NF1FUjMwNDMxIFs4NV1FUjMwNDY1IFs4Nl1FUjMwNTAwIFs4N11FUjMwNTM3IFs4OF1FUjMwNTcyIFs4OV1FUjMwNjA4IFs5MF1FUjMwNjQ0IFs5MV1FUjMwNjkxIFs5Ml1FUjMwNzM1IFs5M11FUjMwODA4IFs5NF1FUjMzMTAzIFs5NV1FUjMzMjAzIFs5Nl1FUjMzMzAzIFs5N11FUjMzNDAzIFs5OV1FUjMzNTAzIFswMV1FUjMzNjAzIFswM11FUjMzNzAzIFswNV1FUjMzODAzIFswN11FUjMzOTAzIFswOV1FUjM0MDAzIFsxMV1FUjM0MTAzIFsxM11FUjM0MjAzIFsxNV1FUjM0MzAzIFsxN11FUjM0NTAzIFsxOV1FUjM0NzAzIFsyMV1FUjM0OTAzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW5kZmlkIHx8IFs2OF1FUjMwMDAxIFs2OV1FUjMwMDIwIFs3MF1FUjMwMDQzIFs3MV1FUjMwMDY3IFs3Ml1FUjMwMDkxIFs3M11FUjMwMTE3IFs3NF1FUjMwMTM4IFs3NV1FUjMwMTYwIFs3Nl1FUjMwMTg4IFs3N11FUjMwMjE3IFs3OF1FUjMwMjQ2IFs3OV1FUjMwMjgzIFs4MF1FUjMwMzEzIFs4MV1FUjMwMzQzIFs4Ml1FUjMwMzczIFs4M11FUjMwMzk5IFs4NF1FUjMwNDI5IFs4NV1FUjMwNDYzIFs4Nl1FUjMwNDk4IFs4N11FUjMwNTM1IFs4OF1FUjMwNTcwIFs4OV1FUjMwNjA2IFs5MF1FUjMwNjQyIFs5MV1FUjMwNjg5IFs5Ml1FUjMwNzMzIFs5M11FUjMwODA2IFs5NF1FUjMzMTAxIFs5NV1FUjMzMjAxIFs5Nl1FUjMzMzAxIFs5N11FUjMzNDAxIFs5OV1FUjMzNTAxIFswMV1FUjMzNjAxIFswM11FUjMzNzAxIFswNV1FUjMzODAxIFswN11FUjMzOTAxIFswOV1FUjM0MDAxIFsxMV1FUjM0MTAxIFsxM11FUjM0MjAxIFsxNV1FUjM0MzAxIFsxN11FUjM0NTAxIFsxOV1FUjM0NzAxIFsyMV1FUjM0OTAxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFtZmlkIHx8IFs2OF1WMyBbNjldVjQ0MiBbNzBdVjExMDIgWzcxXVYxODAyIFs3Ml1WMjQwMiBbNzNdVjMwMDIgWzc0XVYzNDAyIFs3NV1WMzgwMiBbNzZdVjQzMDIgWzc3XVY1MjAyIFs3OF1WNTcwMiBbNzldVjYzMDIgWzgwXVY2OTAyIFs4MV1WNzUwMiBbODJdVjgyMDIgWzgzXVY4ODAyIFs4NF1WMTAwMDIgWzg1XVYxMTEwMiBbODZdVjEyNTAyIFs4N11WMTM3MDIgWzg4XVYxNDgwMiBbODldVjE2MzAyIFs5MF1WMTc3MDIgWzkxXVYxOTAwMiBbOTJdVjIwMzAyIFs5M11WMjE2MDIgWzk0XUVSMjAwMiBbOTVdRVI1MDAyIFs5Nl1FUjcwMDIgWzk3XUVSMTAwMDIgWzk5XUVSMTMwMDIgWzAxXUVSMTcwMDIgWzAzXUVSMjEwMDIgWzA1XUVSMjUwMDIgWzA3XUVSMzYwMDIgWzA5XUVSNDIwMDIgWzExXUVSNDczMDIgWzEzXUVSNTMwMDIgWzE1XUVSNjAwMDIgWzE3XUVSNjYwMDIgWzE5XUVSNzIwMDIgWzIxXUVSNzgwMDIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3bHRoaWQgfHwgWzg0XVMxMDEgWzg5XVMyMDEgWzk0XVMzMDEgWzk5XVM0MDEgWzAxXVM1MDEgWzAzXVM2MDEiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gInNlcGFyYXRlZCIpLCB5ZWFyICVpbiUgeWVhcl90b3JlYWQpCiAgaWYgKHR5cGUgPT0gInBhY2thZ2UiKSB7CiAgICBpbmRfZmlsZW5hbWUgPC0gbGlzdC5maWxlcyhwYXRoID0gaW5kaXIsIHBhdHRlcm4gPSAiaW5kLipcXC5yZGEiKQogICAgbG9hZChmaWxlID0gZmlsZS5wYXRoKGluZGlyLCBpbmRfZmlsZW5hbWUpLCBlbnZpciA9IHRlbXBfZW52KQogICAgbWF0Y2hlcyA8LSBscyhwYXR0ZXJuID0gIi4qaW5kLioiLCBlbnZpciA9IHRlbXBfZW52KQogICAgaWYgKGxlbmd0aChtYXRjaGVzKSA+IDApIHsKICAgICAgdGVtcF9lbnYkaW5kX2RmIDwtIGdldChtYXRjaGVzWzFdLCBlbnZpciA9IHRlbXBfZW52KQogICAgICBybShsaXN0ID0gbWF0Y2hlc1sxXSwgZW52aXIgPSB0ZW1wX2VudikKICAgIH0KICAgIGVsc2UgewogICAgICBzdG9wKCJQbGVhc2UgY2hlY2sgaWYgeW91IGhhdmUgY3Jvc3MteWVhciBpbmRpdmlkdWFsIGZpbGUgaW4gdGhlIGRpcmVjdG9yeSIpCiAgICB9CiAgICBwc2lkX2RmIDwtIGRwbHlyOjpzZWxlY3QoZHBseXI6Om11dGF0ZShkcGx5cjo6c2VsZWN0KHRlbXBfZW52JGluZF9kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsX29mKG5hLm9taXQoYygiRVIzMDAwMSIsICJFUjMwMDAyIiwgdGVtcF9lbnYka2V5X3RiJGluZGZpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wX2VudiRrZXlfdGIkeHNxbnIsIHRlbXBfZW52JGtleV90YiRyZWwyaGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR2YXJzKSkpKSwgcGlkID0gRVIzMDAwMSAqIDEwMDAgKyBFUjMwMDAyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtRVIzMDAwMSwgLUVSMzAwMDIpCiAgICB2YXJsaXN0X3RvcmVhZCA8LSBzZXRkaWZmKHZhcmxpc3RfdG9yZWFkLCBjb2xuYW1lcyhwc2lkX2RmKSkKICAgIHZhcmxpc3RfdGVtcCA8LSBpbnRlcnNlY3QodmFybGlzdF90b3JlYWQsIGNvbG5hbWVzKHRlbXBfZW52JGluZF9kZikpCiAgICB0ZW1wX2VudiRpbmRjeV9kZiA8LSBkcGx5cjo6c2VsZWN0KGRwbHlyOjptdXRhdGUoZHBseXI6OnNlbGVjdCh0ZW1wX2VudiRpbmRfZGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxfb2YoYygiRVIzMDAwMSIsICJFUjMwMDAyIiwgdmFybGlzdF90ZW1wKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpZCA9IEVSMzAwMDEgKiAxMDAwICsgRVIzMDAwMiksIC1FUjMwMDAxLCAtRVIzMDAwMikKICAgIHBzaWRfZGYgPC0gZHBseXI6OmxlZnRfam9pbihwc2lkX2RmLCB0ZW1wX2VudiRpbmRjeV9kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9ICJwaWQiKQogICAgcm0obGlzdCA9IHNldGRpZmYobHMoZW52aXIgPSB0ZW1wX2VudiksICJrZXlfdGIiKSwgZW52aXIgPSB0ZW1wX2VudikKICAgIGZvciAoeXIgaW4gc3RyX2RmJHllYXIpIHsKICAgICAgZmFtZmlkX3lyIDwtIHVubmFtZSh1bmxpc3QoZHBseXI6OnNlbGVjdChkcGx5cjo6ZmlsdGVyKHRlbXBfZW52JGtleV90YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXIgPT0geXIpLCBmYW1maWQpKSkKICAgICAgaW5kZmlkX3lyIDwtIHVubmFtZSh1bmxpc3QoZHBseXI6OnNlbGVjdChkcGx5cjo6ZmlsdGVyKHRlbXBfZW52JGtleV90YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXIgPT0geXIpLCBpbmRmaWQpKSkKICAgICAgd2x0aGlkX3lyIDwtIHVubmFtZSh1bmxpc3QoZHBseXI6OnNlbGVjdChkcGx5cjo6ZmlsdGVyKHRlbXBfZW52JGtleV90YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXIgPT0geXIpLCB3bHRoaWQpKSkKICAgICAgbGlzdF92YXJ5ZWFyIDwtIHVubmFtZSh1bmxpc3QoZHBseXI6OnNlbGVjdChkcGx5cjo6ZmlsdGVyKHN0cl9kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXIgPT0geXIpLCAteWVhcikpKQogICAgICBsaXN0X3ZhcnllYXIgPC0gc2V0ZGlmZihsaXN0X3ZhcnllYXJbIWlzLm5hKGxpc3RfdmFyeWVhcildLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xuYW1lcyhwc2lkX2RmKSkKICAgICAgaWYgKGxlbmd0aChsaXN0X3ZhcnllYXIpID4gMCkgewogICAgICAgIGlmIChpcy5uYSh3bHRoaWRfeXIpKSB7CiAgICAgICAgICBuYW1lX2ZhbV9kZiA8LSBsaXN0LmZpbGVzKHBhdGggPSBpbmRpciwgcGF0dGVybiA9IHBhc3RlKCIuKmZhbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlyLCAiLipcXC5yZGEiLCBzZXAgPSAiIikpCiAgICAgICAgICBsb2FkKGZpbGUgPSBwYXN0ZShpbmRpciwgbmFtZV9mYW1fZGYsIHNlcCA9ICIvIiksCiAgICAgICAgICAgICAgIGVudmlyID0gdGVtcF9lbnYpCiAgICAgICAgICBtYXRjaGVzIDwtIGxzKHBhdHRlcm4gPSBwYXN0ZSgiLipmYW0iLCB5ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIuKiIsIHNlcCA9ICIiKSwgZW52aXIgPSB0ZW1wX2VudikKICAgICAgICAgIGlmIChsZW5ndGgobWF0Y2hlcykgPiAwKSB7CiAgICAgICAgICAgIHRlbXBfZW52JGZhbV9kZiA8LSBkcGx5cjo6c2VsZWN0KGdldChtYXRjaGVzWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXIgPSB0ZW1wX2VudiksIGFsbF9vZihjKGZhbWZpZF95ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0X3ZhcnllYXIpKSkKICAgICAgICAgICAgcm0obGlzdCA9IG1hdGNoZXNbMV0sIGVudmlyID0gdGVtcF9lbnYpCiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgc3RvcCgiUGxlYXNlIGNoZWNrIGlmIHlvdSBoYXZlIG5lY2Vzc2FyeSBmYW1pbHkgcGFja2FnZWQgZmlsZSBpbiB0aGUgZGlyZWN0b3J5IikKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICBuYW1lX2ZhbV9kZiA8LSBsaXN0LmZpbGVzKHBhdGggPSBpbmRpciwgcGF0dGVybiA9IHBhc3RlKCIuKmZhbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlyLCAiLipcXC5yZGEiLCBzZXAgPSAiIikpCiAgICAgICAgICBsb2FkKGZpbGUgPSBwYXN0ZShpbmRpciwgbmFtZV9mYW1fZGYsIHNlcCA9ICIvIiksCiAgICAgICAgICAgICAgIGVudmlyID0gdGVtcF9lbnYpCiAgICAgICAgICBtYXRjaGVzIDwtIGxzKHBhdHRlcm4gPSBwYXN0ZSgiLipmYW0iLCB5ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIuKiIsIHNlcCA9ICIiKSwgZW52aXIgPSB0ZW1wX2VudikKICAgICAgICAgIGlmIChsZW5ndGgobWF0Y2hlcykgPiAwKSB7CiAgICAgICAgICAgIHRlbXBfZW52JGZhbV9kZiA8LSBnZXQobWF0Y2hlc1sxXSwgZW52aXIgPSB0ZW1wX2VudikKICAgICAgICAgICAgcm0obGlzdCA9IG1hdGNoZXNbMV0sIGVudmlyID0gdGVtcF9lbnYpCiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgc3RvcCgiUGxlYXNlIGNoZWNrIGlmIHlvdSBoYXZlIG5lY2Vzc2FyeSBmYW1pbHkgcGFja2FnZWQgZmlsZSBpbiB0aGUgZGlyZWN0b3J5IikKICAgICAgICAgIH0KICAgICAgICAgIG5hbWVfd2x0aF9kZiA8LSBsaXN0LmZpbGVzKHBhdGggPSBpbmRpciwgcGF0dGVybiA9IHBhc3RlKCIuKndsdGgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeXIsICIuKlxcLnJkYSIsIHNlcCA9ICIiKSkKICAgICAgICAgIGxvYWQoZmlsZSA9IHBhc3RlKGluZGlyLCBuYW1lX3dsdGhfZGYsIHNlcCA9ICIvIiksCiAgICAgICAgICAgICAgIGVudmlyID0gdGVtcF9lbnYpCiAgICAgICAgICBtYXRjaGVzIDwtIGxzKHBhdHRlcm4gPSBwYXN0ZSgiLip3bHRoIiwgeXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLioiLCBzZXAgPSAiIiksIGVudmlyID0gdGVtcF9lbnYpCiAgICAgICAgICBpZiAobGVuZ3RoKG1hdGNoZXMpID4gMCkgewogICAgICAgICAgICB0ZW1wX2VudiR3bHRoX2RmIDwtIGdldChtYXRjaGVzWzFdLCBlbnZpciA9IHRlbXBfZW52KQogICAgICAgICAgICBybShsaXN0ID0gbWF0Y2hlc1sxXSwgZW52aXIgPSB0ZW1wX2VudikKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgewogICAgICAgICAgICBzdG9wKCJQbGVhc2UgY2hlY2sgaWYgeW91IGhhdmUgbmVjZXNzYXJ5IHdlYWx0aCBwYWNrYWdlZCBmaWxlIGluIHRoZSBkaXJlY3RvcnkiKQogICAgICAgICAgfQogICAgICAgICAgYnlfdmVjdG9yIDwtIHNldE5hbWVzKG5tID0gZmFtZmlkX3lyLCBvYmplY3QgPSB3bHRoaWRfeXIpCiAgICAgICAgICB0ZW1wX2VudiRmYW1fZGYgPC0gZHBseXI6OnNlbGVjdChkcGx5cjo6bGVmdF9qb2luKHRlbXBfZW52JGZhbV9kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcF9lbnYkd2x0aF9kZiwgYnkgPSBieV92ZWN0b3IpLCBhbGxfb2YoYyhmYW1maWRfeXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdF92YXJ5ZWFyKSkpCiAgICAgICAgfQogICAgICAgIGJ5X3ZlY3RvciA8LSBzZXROYW1lcyhubSA9IGluZGZpZF95ciwgb2JqZWN0ID0gZmFtZmlkX3lyKQogICAgICAgIHBzaWRfZGYgPC0gZHBseXI6OmxlZnRfam9pbihwc2lkX2RmLCB0ZW1wX2VudiRmYW1fZGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gYnlfdmVjdG9yKQogICAgICAgIHJtKGxpc3QgPSBzZXRkaWZmKGxzKGVudmlyID0gdGVtcF9lbnYpLCAia2V5X3RiIiksCiAgICAgICAgICAgZW52aXIgPSB0ZW1wX2VudikKICAgICAgICBtZXNzYWdlKCJEYXRhIGZvciB5ZWFyICIsIHlyLCAiIGhhcyBiZWVuIGFkZGVkISIpCiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgKG5leHQpKHBhc3RlKCJObyBkYXRhIGZvciB5ZWFyICIsIHlyLCAiIGhhcyBiZWVuIGFkZGVkISIsCiAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIiKSkKICAgICAgfQogICAgfQogICAgcm93U3Vtcyhwc2lkX2RmWywgdGVtcF9lbnYka2V5X3RiJGluZGZpZF0pCiAgICBwc2lkX2RmIDwtIHBzaWRfZGZbd2hpY2gocm93U3Vtcyhwc2lkX2RmWywgdGVtcF9lbnYka2V5X3RiJGluZGZpZF0pID4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApLCBdCiAgfQogIGVsc2UgaWYgKHR5cGUgPT0gInNpbmdsZSIpIHsKICAgIHZhcmxpc3RfZmluYWwgPC0gdW5pb24odmFybGlzdF90b3JlYWQsIHVubmFtZSh1bmxpc3QodGVtcF9lbnYka2V5X3RiWywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoInhzcW5yIiwgInJlbDJoaCIsICJpbmRmaWQiKV0pKSkKICAgIGxvYWQoZmlsZSA9IHBhc3RlKGluZGlyLCBwYXN0ZShzdWIoIlxcLnppcCQiLCAiIiwgZmlsZW5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIucmRhIiwgc2VwID0gIiIpLCBzZXAgPSAiLyIpLCBlbnZpciA9IHRlbXBfZW52KQogICAgcHNpZF9kZiA8LSBkcGx5cjo6c2VsZWN0KGRwbHlyOjptdXRhdGUoZHBseXI6OnNlbGVjdChnZXQoc3ViKCJcXC56aXAkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIiwgZmlsZW5hbWUpLCBlbnZpciA9IHRlbXBfZW52KSwgYWxsX29mKG5hLm9taXQoYygiRVIzMDAwMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVSMzAwMDIiLCB2YXJsaXN0X2ZpbmFsLCBpZHZhcnMpKSkpLCBwaWQgPSBFUjMwMDAxICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTAwMCArIEVSMzAwMDIpLCAtRVIzMDAwMSwgLUVSMzAwMDIpCiAgfQogIGVsc2UgewogICAgc3RvcCgiUGxlYXNlIHNwZWNpZnkgd2hldGhlciB5b3VyIFBTSUQgZGF0YSBpcyAncGFja2FnZScgb3IgJ3NpbmdsZSchIikKICB9CiAgcmV0dXJuKHBzaWRfZGYpCn0KCiMjIHJlYWQgYW5kIHJlc2hhcGUgZGF0YWZyYW1lIAoKcHNpZF9kZiA8LSBwc2lkX3JlYWRfZml4ZWQoaW5kaXIgPSBvdXRwdXRfZGlyZWN0b3J5LCBzdHJfZGYgPSBzdHJfZGYsaWR2YXJzID0gYygiRVIzMDAwMCIpLHR5cGUgPSAicGFja2FnZSIsIGZpbGVuYW1lID0gTkEpCmRmIDwtIHBzaWRfcmVzaGFwZShwc2lkX2RmID0gcHNpZF9kZiwgc3RyX2RmID0gc3RyX2RmLCBzaGFwZSA9ICJsb25nIiwgbGV2ZWwgPSAiaG91c2Vob2xkIikKCiMjIGNsZWFuIFVTIAoKZGZfbmV3IDwtIGRmICU+JSAKICBtdXRhdGUoCiAgICBoaF9zdGF0ZSA9IHJlcGxhY2UoaGhfc3RhdGUsIGhoX3N0YXRlID09IDAsIE5BKSwjIE1ha2UgVVMgdGVycml0b3JpZXMgaW50byBOQQogICAgaGhfcm9vbXMgPSByZXBsYWNlKGhoX3Jvb21zLCBoaF9yb29tcyAlaW4lIGMoOTgsIDk5KSwgTkEpLCMgUmVtb3ZlICJkb24ndCBrbm93IiBvbiByb29tcwogICAgaGhfb3duID0gcmVwbGFjZShoaF9vd24sIGhoX293biA9PSA4LCBOQSksIyBOQSBmb3IgbmVpdGhlciBvd24gbm9yIHJlbnQgKDgpCiAgICBoaF90eXBlID0gcmVwbGFjZShoaF90eXBlLCBoaF90eXBlICVpbiUgYyg3LCA4LCA5KSwgTkEpLCAjIFJlbW92ZSBkb24ndCBrbm93IG9uIGhvdXNpbmcgdHlwZQogICAgZ292dF9ydF9hbGwgPSByZXBsYWNlKGdvdnRfcnRfYWxsLCBnb3Z0X3J0X2FsbCAlaW4lIGMoOCwgOSwgMCksIE5BKSwgIyByZW1vdmUgZG9udCBrbm93CiAgICBnb3Z0X3J0X3BhcnQgPSByZXBsYWNlKGdvdnRfcnRfcGFydCwgZ292dF9ydF9wYXJ0ICVpbiUgYyg4LCA5LCAwKSwgTkEpLCAjIE5BIGZvciBkb250IGtub3cKICAgIGhoX3ZhbHVlID0gcmVwbGFjZShoaF92YWx1ZSwgaGhfdmFsdWUgJWluJSBjKDk5OTk5OTk5OCwgOTk5OTk5OTk5LCAwKSwgTkEpLCAgIyBOQSBmb3Igc3BlY2lmaWMgaW52YWxpZCBoaF92YWx1ZQogICAgZ2FzX2V4cCA9IHJlcGxhY2UoZ2FzX2V4cCwgZ2FzX2V4cCAlaW4lIGMoOTk5NywgOTk5OCwgOTk5OSwgMCksIE5BKSwgIyBOQSBmb3IgREsgYW5kIAogICAgZWxlY19leHAgPSByZXBsYWNlKGVsZWNfZXhwLCBlbGVjX2V4cCAlaW4lIGMoOTk5NywgOTk5OCwgOTk5OSwgMCksIE5BKSwgCiAgICBoZWF0X21ldGhvZCA9IHJlcGxhY2UoaGVhdF9tZXRob2QsIGhlYXRfbWV0aG9kICVpbiUgYyg5NywgOTgsIDk5LCAwKSwgTkEpLCAKICAgIGdvdnRfaGVhdF9hc3NpdGFuY2UgPSByZXBsYWNlKGdvdnRfaGVhdF9hc3NpdGFuY2UsIGdvdnRfaGVhdF9hc3NpdGFuY2UgJWluJSBjKDk5OTcsIDk5OTgsIDk5OTksIDApLCBOQSksIAogICAgcnBfZXRoID0gcmVwbGFjZShycF9ldGgsIHJwX2V0aCAlaW4lIGMoOTcsIDk5LCAwKSwgTkEpLCAKICAgIGhoX2luY29tZSA9IHJlcGxhY2UoaGhfaW5jb21lLCBoaF9pbmNvbWUgPD0gMCwgTkEpLCAjIyBzdXJ2eWUgaGFzIDAgYXMgaW5uYXByb3ByaWF0ZSwgbm90IG5vIGluY29tZQogICAgZ2FzX2FfZXhwID0gcmVwbGFjZShnYXNfYV9leHAsIGdhc19hX2V4cCA9PSA5OTk5OTk5LCBOQSksCiAgICBlbGVjX2FfZXhwID0gcmVwbGFjZShlbGVjX2FfZXhwLCBlbGVjX2FfZXhwID09IDk5OTk5OTksIE5BKSwKICAgIHJlZl93YWdlID0gcmVwbGFjZSAocmVmX3dhZ2UsIHJlZl93YWdlICVpbiUgYyg5OTk5OTk3LCA5OTk5OTk4LCA5OTk5OTk5LCAwKSwgTkEpLAogICAgc3BvdXNlX3dhZ2UgPSByZXBsYWNlKHNwb3VzZV93YWdlLCBzcG91c2Vfd2FnZSAlaW4lIGMoOTk5OTk5NywgOTk5OTk5OCwgOTk5OTk5OSwgMCksIE5BKSwgCiAgICByZWZfd2VsZmFyZSA9IHJlcGxhY2UocmVmX3dlbGZhcmUsIHJlZl93ZWxmYXJlICVpbiUgYyg5OTk5OTcsIDk5OTk5OCwgOTk5OTk5LCAwKSwgTkEpLAogICAgc3BvdXNlX3dlbGZhcmUgPSByZXBsYWNlKHNwb3VzZV93ZWxmYXJlLCBzcG91c2Vfd2VsZmFyZSAlaW4lIGMoOTk5OTk3LCA5OTk5OTgsIDk5OTk5OSwgMCksIE5BKSwKICAgIG90aGVyX3dlbGZhcmUgPSByZXBsYWNlKG90aGVyX3dlbGZhcmUsIG90aGVyX3dlbGZhcmUgJWluJSBjKDk5OTk5NywgOTk5OTk4LCA5OTk5OTksIDApLCBOQSkKICApCgojIyMgY3JlYXRlIHR0bGVuZXIKCmZpbHRlcmVkX3N1YnNldCA8LSBkZl9uZXcgJT4lCiAgbXV0YXRlKAogICAgdHRsZW5lciA9IGlmZWxzZSghaXMubmEoZWxlY19hX2V4cCkgJiAhaXMubmEoZ2FzX2FfZXhwKSwgZWxlY19hX2V4cCArIGdhc19hX2V4cCwKICAgICAgICAgICAgICBpZmVsc2UoIWlzLm5hKGVsZWNfYV9leHApLCBlbGVjX2FfZXhwLAogICAgICAgICAgICAgIGlmZWxzZSghaXMubmEoZ2FzX2FfZXhwKSwgZ2FzX2FfZXhwLCBOQSkpKQogICkKCiMjIyBjbGVhbiBkYXRhIAoKZmlsdGVyZWRfc3Vic2V0IDwtIGZpbHRlcmVkX3N1YnNldCAlPiUKICAgICAgICBmaWx0ZXIoIShwaWQgPT0gNTQ5MTAwNSAmIHllYXIgPT0gMjAwOSksCiAgICAgICAgICAgICAgICEocGlkID09IDMwMzgwMDEgJiB5ZWFyID09IDIwMDUpLCAKICAgICAgICAgICAgICAgIShwaWQgPT0gMjYxNTAzMiAmIHllYXIgPT0gMjAwOSksIAogICAgICAgICAgICAgICAhKHBpZCA9PSAyMzkxMTc5ICYgeWVhciA9PSAyMDA3KSwgCiAgICAgICAgICAgICAgICEocGlkID09IDEwODQwMDcgJiB5ZWFyID09IDIwMTUpLAogICAgICAgICAgICAgICAhKHBpZCA9PSA2MjAxNzEgJiB5ZWFyID09IDIwMTMpLAogICAgICAgICAgICAgICAhKHBpZCA9PSA1OTcwMDMgJiB5ZWFyID09IDIwMTEpKQoKIyMgY3JlYXRlIGRlY2lsZSAKCmZpbHRlcmVkX3N1YnNldCA8LSBmaWx0ZXJlZF9zdWJzZXQgJT4lCiAgZmlsdGVyKHR0bGVuZXIgPj0gMSkgJT4lCiAgZmlsdGVyKGhoX2luY29tZSA+IDUwMCkgJT4lCiAgbXV0YXRlKHllYXIgPSBhcy5udW1lcmljKHllYXIpKSAlPiUKICAgICAgICBncm91cF9ieSh5ZWFyKSAlPiUKICAgICAgICBtdXRhdGUoZGVjaWxlID0gbnRpbGUoaGhfaW5jb21lLCAxMCkpICU+JQogICAgICAgIHVuZ3JvdXAoKQoKIyMgY3JlYXRlIGVuZXJneSBleHBlbmRpdHVyZSAKCmZpbHRlcmVkX3N1YnNldCA8LSBmaWx0ZXJlZF9zdWJzZXQgJT4lCiAgbXV0YXRlKGVuZXhwID0gaWZlbHNlKGhoX2luY29tZSA+IDAsICh0dGxlbmVyIC8gaGhfaW5jb21lKSAqIDEwMCwgTkEpKSAlPiUgIyMgY3JlYXRpbmcgJSBzcGVudCBvbiBlbmVyZ3kgc2VydmljZXMgdGFiIAogIG11dGF0ZShlbmV4cF90ID0gaWZlbHNlKGhoX2luY29tZSA+IDAsICgodHRsZW5lciArIHBldHJvbF9hX2V4cCkgLyBoaF9pbmNvbWUpICogMTAwLCBOQSkpICMjIGFsbCBlbmVyZ3kgYW5kIHRyYW5zcG9ydCBjb3N0cwoKVVMgPC0gZmlsdGVyZWRfc3Vic2V0CgpgYGAKCmBgYHtyIGxvYWQgVUsgREVVLCBpbmNsdWRlPUZBTFNFfQoKVUsgPC0gcmVhZF9jc3YoIn4vRG9jdW1lbnRzL0dpdGh1Yi9QaEQvRGF0YS9VS19DbGVhbi5jc3YiKQpERVUgPC0gcmVhZF9jc3YoIn4vRG9jdW1lbnRzL0dpdGh1Yi9QaEQvRGF0YS9ERVVfQ2xlYW4uY3N2Iiwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkKCmBgYAoKIyMgU3RlcCAxOiBVcHRha2UgUmF0ZXMKClRoaXMgcHJvdmlkZXMgYSBzbmFwc2hvdCBmb3IgY3VycmVudCB1cHRha2UgYWNyb3NzIHRoZSBob3VzZWhvbGRzIGFzc2Vzc2luZyBoZXRlcm9nZW5laXR5IGFjcm9zcyBpbmNvbWUgbGV2ZWwuCgojIyMgVS5TLiBVcHRha2UgUmF0ZXMKCkZvciB0aGUgVVMsIEkgaGF2ZSBpbmZvcm1hdGlvbiBmb3Igc29sYXIgb3duZXJzaGlwLCBFVi8gaHlicmlkIG93bmVyc2hpcCwgc21hcnRwaG9uZSBvd25lcnNoaXAsIGludGVybmV0IGFjY2VzcywgYW5kIGNvbW11dGUgaGFiaXQuIEkgY3JlYXRlIGFuIGFkZGl0aW9uYWwgdmFyaWFibGUgb24gZnVlbCBzd2l0Y2hpbmcgYnkgbG9va2luZyBhdCBoZWF0aW5nIG1ldGhvZCBhbmQgc2VlaW5nIHdoZXJlIG1vdmVkIGZyb20gd29vZCwgb2lsLCBnYXMsIGNvYWwgdG8gZWxlY3RyaWMgaGVhdGluZy4gSSBhbHNvIGNyZWF0ZSBhIHZhcmlhYmxlIGZvciByZXRyb2ZpdHRpbmcgYmFzZWQgb24gaG9tZSByZW5vdmF0aW9ucyBhbmQgc2tpbGxzIGJhc2VkIG9uIHN1cnZleSByZXNwb25zZXMgd2hlcmUgUlAgcmVzcG9uZHMgdGhleSB1c2UgdGhlIGludGVybmV0IGRhaWx5LgoKTm90ZTogU21hcnRwaG9uZSBvd25lcnNoaXAgYW5kIGRpZ2l0YWwgc2tpbGxzIHF1ZXN0aW9ucyB3ZXJlIG9ubHkgYWRkZWQgdG8gdGhlIHN1cnZleSBpbiAyMDE1LgoKYGBge3IgVVMgVXB0YWtlIFJhdGVzLCBlY2hvPUZBTFNFfQpVUyA8LSBVUyAlPiUKICBncm91cF9ieShwaWQpICU+JQogIGFycmFuZ2UocGlkLCB5ZWFyKSAlPiUKICBtdXRhdGUoCiAgICAjIENyZWF0ZSBhIGNvbWJpbmVkIHNvbGFyIGluZGljYXRvcgogICAgaXNfc29sYXIgPSBoZWF0X21ldGhvZCA9PSA2IHwgaGVhdF9tZXRob2RfMiA9PSA2IHwgaGVhdF9tZXRob2RfMyA9PSA2LAogICAgCiAgICAjIFRyYWNrIHRob3NlIHdobyBzd2l0Y2hlZCB0byBlbGVjdHJpYwogICAgc3dpdGNoZWRfdG9fZWxlY3RyaWMgPSBsYWcoaGVhdF9tZXRob2QpICVpbiUgYygxLDMsNCw1LDEwLDExKSAmIAogICAgICAgICAgICAgICAgICAgICAgICAgIGhlYXRfbWV0aG9kID09IDIsCiAgICAKICAgICMgVHJhY2sgdGhvc2UgYWx3YXlzIG9uIGVsZWN0cmljCiAgICBhbHdheXNfZWxlY3RyaWMgPSBhbGwoaGVhdF9tZXRob2QgPT0gMiwgbmEucm0gPSBUUlVFKSwKICAgIAogICAgIyBUcmFjayB0aG9zZSB3aG8gc3dpdGNoZWQgdG8gc29sYXIgKHVzaW5nIGFueSBvZiB0aGUgdGhyZWUgbWV0aG9kcykKICAgIHN3aXRjaGVkX3RvX3NvbGFyID0gbGFnKGlzX3NvbGFyKSA9PSBGQUxTRSAmIGlzX3NvbGFyID09IFRSVUUsCiAgICAKICAgICMgVHJhY2sgdGhvc2UgYWx3YXlzIG9uIHNvbGFyCiAgICBhbHdheXNfc29sYXIgPSBhbGwoaXNfc29sYXIsIG5hLnJtID0gVFJVRSksCiAgICAKICAgICMgQ29tYmluZWQgbWVhc3VyZXM6IGVpdGhlciBzd2l0Y2hlZCBvciBhbHdheXMgYmVlbiBvbiB0aGF0IG1ldGhvZAogICAgdXNpbmdfZWxlY3RyaWMgPSBoZWF0X21ldGhvZCA9PSAyLAogICAgdXNpbmdfc29sYXIgPSBpc19zb2xhciwKICAgIAogICAgIyBTd2l0Y2ggeWVhcnMKICAgIHN3aXRjaF95ZWFyX2VsZWN0cmljID0gY2FzZV93aGVuKAogICAgICBzd2l0Y2hlZF90b19lbGVjdHJpYyB+IHllYXIsCiAgICAgIFRSVUUgfiBOQV9yZWFsXwogICAgKSwKICAgIHN3aXRjaF95ZWFyX3NvbGFyID0gY2FzZV93aGVuKAogICAgICBzd2l0Y2hlZF90b19zb2xhciB+IHllYXIsCiAgICAgIFRSVUUgfiBOQV9yZWFsXwogICAgKQogICkgJT4lCiAgdW5ncm91cCgpICU+JQogIGZpbHRlcih5ZWFyID4gMjAxMCkKIyBGb3IgZGVjaWxlIGFuYWx5c2lzOgp1cHRha2VfcmF0ZXMgPC0gVVMgJT4lCiAgZ3JvdXBfYnkoeWVhciwgZGVjaWxlKSAlPiUKICBzdW1tYXJpc2UoCiAgICB0b3RhbF9ob3VzZWhvbGRzID0gbl9kaXN0aW5jdChwaWQpLAogICAgCiAgICAjIEVsZWN0cmljIGhlYXRpbmcgbWV0cmljcwogICAgbmV3X2VsZWN0cmljX3N3aXRjaGVzID0gc3VtKHN3aXRjaGVkX3RvX2VsZWN0cmljLCBuYS5ybSA9IFRSVUUpLAogICAgdG90YWxfZWxlY3RyaWNfdXNlcnMgPSBzdW0odXNpbmdfZWxlY3RyaWMsIG5hLnJtID0gVFJVRSksCiAgICAKICAgICMgU29sYXIgaGVhdGluZyBtZXRyaWNzCiAgICBuZXdfc29sYXJfc3dpdGNoZXMgPSBzdW0oc3dpdGNoZWRfdG9fc29sYXIsIG5hLnJtID0gVFJVRSksCiAgICB0b3RhbF9zb2xhcl91c2VycyA9IHN1bSh1c2luZ19zb2xhciwgbmEucm0gPSBUUlVFKSwKICAgIAogICAgIyBDYWxjdWxhdGUgcmF0ZXMKICAgIGVsZWN0cmljX3N3aXRjaF9yYXRlID0gKG5ld19lbGVjdHJpY19zd2l0Y2hlcyAvIHRvdGFsX2hvdXNlaG9sZHMpICogMTAwLAogICAgdG90YWxfZWxlY3RyaWNfcmF0ZSA9ICh0b3RhbF9lbGVjdHJpY191c2VycyAvIHRvdGFsX2hvdXNlaG9sZHMpICogMTAwLAogICAgc29sYXJfc3dpdGNoX3JhdGUgPSAobmV3X3NvbGFyX3N3aXRjaGVzIC8gdG90YWxfaG91c2Vob2xkcykgKiAxMDAsCiAgICB0b3RhbF9zb2xhcl9yYXRlID0gKHRvdGFsX3NvbGFyX3VzZXJzIC8gdG90YWxfaG91c2Vob2xkcykgKiAxMDAKICApICU+JQogIHVuZ3JvdXAoKQoKdXNfcHJvcHMgPC0gVVMgJT4lCiAgZ3JvdXBfYnkoeWVhciwgZGVjaWxlKSAlPiUKICBzdW1tYXJpc2UoCiAgICBuX3RvdGFsID0gbigpLAogICAgc21hcnRwaG9uZV9wcm9wID0gbWVhbihzbWFydHBob25lID09IDEsIG5hLnJtID0gVFJVRSksCiAgICBoeWJyaWRfcHJvcCA9IG1lYW4oaHlicmlkID09IDEgfCBoeWJyaWRfMiA9PSAxIHwgaHlicmlkXzMgPT0gMSwgbmEucm0gPSBUUlVFKSwgIyBpbmNsdWRlcyBFVnMgCiAgICBzb2xhcl9wcm9wID0gbWVhbihoZWF0X21ldGhvZCA9PSA2IHwgaGVhdF9tZXRob2RfMiA9PTYgfCBoZWF0X21ldGhvZF8zID09IDYsIG5hLnJtID0gVFJVRSksCiAgICBpbnRlcm5ldF9wcm9wID0gbWVhbihjb21wdXRlciA9PSAxLCBuYS5ybSA9IFRSVUUpLCAgICAgIyBDb21wdXRlciBvd25lcnNoaXAKICAgIHJlcGFpcnNfcHJvcCA9IG1lYW4oaGhfcmVwYWlyID4gMSwgbmEucm0gPSBUUlVFKSwgCiAgICBza2lsbHNfcHJvcCA9IG1lYW4oaW50ZXJuZXQgPT0gMSwgbmEucm0gPSBUUlVFKSwgICAgICAgIyBJbnRlcm5ldCB1c2FnZQogICAgZnVlbF9zd2l0Y2hfcHJvcCA9IG1lYW4oaGVhdF9tZXRob2QgPT0gMiAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAhKGhlYXRfbWV0aG9kXzIgJWluJSBjKDEsMyw0LDUsMTAsMTEpIHwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhdF9tZXRob2RfMyAlaW4lIGMoMSwzLDQsNSwxMCwxMSkpLCBuYS5ybSA9IFRSVUUpCiAgKSAlPiUKICBtdXRhdGUoCiAgICBzbWFydHBob25lX3BlcmNlbnQgPSBzbWFydHBob25lX3Byb3AgKiAxMDAsICAgICAgICAgICAgIyBSZW1vdmUgZHVwbGljYXRlIGxpbmUKICAgIGh5YnJpZF9wZXJjZW50ID0gaHlicmlkX3Byb3AgKiAxMDAsCiAgICBzb2xhcl9wZXJjZW50ID0gc29sYXJfcHJvcCAqIDEwMCwgCiAgICBpbnRlcm5ldF9wZXJjZW50ID0gaW50ZXJuZXRfcHJvcCAqIDEwMCwgCiAgICByZXBhaXJzX3BlcmNlbnQgPSByZXBhaXJzX3Byb3AgKiAxMDAsIAogICAgc2tpbGxzX3BlcmNlbnQgPSBza2lsbHNfcHJvcCAqIDEwMCwKICAgIGZ1ZWxfc3dpdGNoX3BlcmNlbnQgPSBmdWVsX3N3aXRjaF9wcm9wICogMTAwIAogICkKCgp1c19wcm9wc19sb25nIDwtIHVzX3Byb3BzICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBjKHNtYXJ0cGhvbmVfcGVyY2VudCwgaHlicmlkX3BlcmNlbnQsIHNvbGFyX3BlcmNlbnQsIAogICAgICAgICAgICAgaW50ZXJuZXRfcGVyY2VudCwgcmVwYWlyc19wZXJjZW50LCBza2lsbHNfcGVyY2VudCwgCiAgICAgICAgICAgICBmdWVsX3N3aXRjaF9wZXJjZW50KSwKICAgIG5hbWVzX3RvID0gInRlY2hub2xvZ3kiLAogICAgdmFsdWVzX3RvID0gInBlcmNlbnRhZ2UiCiAgKSAlPiUKICBtdXRhdGUodGVjaG5vbG9neSA9IGZhY3Rvcih0ZWNobm9sb2d5LCAKICAgIGxldmVscyA9IGMoInNtYXJ0cGhvbmVfcGVyY2VudCIsICJoeWJyaWRfcGVyY2VudCIsICJzb2xhcl9wZXJjZW50IiwgCiAgICAgICAgICAgICAgICJpbnRlcm5ldF9wZXJjZW50IiwgInJlcGFpcnNfcGVyY2VudCIsICJza2lsbHNfcGVyY2VudCIsIAogICAgICAgICAgICAgICAiZnVlbF9zd2l0Y2hfcGVyY2VudCIpLAogICAgbGFiZWxzID0gYygiU21hcnRwaG9uZSIsICJIeWJyaWQvRVYiLCAiU29sYXIgUGFuZWxzIiwgIkludGVybmV0IiwgCiAgICAgICAgICAgICAgICJIb21lIFJlbm92YXRpb25zIiwgIkRpZ2l0YWwgU2tpbGxzIiwgIkNsZWFuIEhlYXRpbmcgU3dpdGNoIikpKQoKIyBDcmVhdGUgdGhlIHBsb3QKZ2dwbG90KHVzX3Byb3BzX2xvbmcsIGFlcyh4ID0gZGVjaWxlLCB5ID0gcGVyY2VudGFnZSwgY29sb3IgPSB0ZWNobm9sb2d5KSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIGZhY2V0X3dyYXAofnllYXIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJUZWNobm9sb2d5IEFkb3B0aW9uIGJ5IEluY29tZSBEZWNpbGUgaW4gVVMiLAogICAgeCA9ICJJbmNvbWUgRGVjaWxlIiwKICAgIHkgPSAiUGVyY2VudGFnZSBvZiBIb3VzZWhvbGRzICglKSIsCiAgICBjb2xvciA9ICJUZWNobm9sb2d5IgogICkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAxOjEwKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGxlZ2VuZC5ib3ggPSAidmVydGljYWwiLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQogICkgKwogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChucm93ID0gMikpICMgTWFrZXMgbGVnZW5kIG1vcmUgY29tcGFjdAoKIyBQbG90IGFjcm9zcyB0aW1lCmdncGxvdCh1c19wcm9wc19sb25nLCBhZXMoeCA9IHllYXIsIHkgPSBwZXJjZW50YWdlLCBjb2xvciA9IHRlY2hub2xvZ3kpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgZmFjZXRfd3JhcCh+ZGVjaWxlKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKAogICAgdGl0bGUgPSAiVGVjaG5vbG9neSBBZG9wdGlvbiBPdmVyIFRpbWUgYnkgSW5jb21lIERlY2lsZSIsCiAgICB4ID0gIlllYXIiLAogICAgeSA9ICJQZXJjZW50YWdlIG9mIEhvdXNlaG9sZHMgKCUpIiwKICAgIGNvbG9yID0gIlRlY2hub2xvZ3kiCiAgKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGxlZ2VuZC5ib3ggPSAidmVydGljYWwiLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQogICkgKwogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChucm93ID0gMikpCmBgYAoKQ2xlYW4gaGVhdGluZyBpcyBpbnRlcmVzdGluZyBpbiB0aGF0IGhpZ2ggaW5jb21lIGhvdXNlaG9sZHMgaGFkIGxlc3MgZWxlY3RyaWMgb25seSBhbmQgbWFyZ2luYWxseSBpbmNyZWFzZWQgb3ZlciAyMDExIC0gMjAyMSB0aW1lIHBlcmlvZCwgdGhvdWdoIHRoZXkgc3RpbGwgZGlkIGluY3JlYXNlIHdpdGhpbiBkZWNpbGUgOSBhbmQgMTAuIFNvbGFyIHBhbmVsIGluZmlsdHJhdGlvbiBpcyBsb3dlciB0aGFuIG5hdGlvbmFsIGF2ZXJhZ2UgYXQgMSUgd2l0aCBFSUEgZXN0aW1hdGluZyA0JS4KCiMjIyBVLksuIFVwdGFrZSBSYXRlcwoKRm9yIHRoZSBVSywgSSBoYXZlIHNvbGFyLCBFVi8gaHlicmlkLCBzbWFydHBob25lLCBpbnRlcm5ldCwgY29tbXV0ZSBhbmQgc2tpbGxzLiBJIGNyZWF0ZSBmdWVsIHN3aXRjaGluZyBpbiB0aGUgc2FtZSBtYW5uZXIgYXMgZm9yIFVTLCBidXkgbG9va2luZyBhdCBob21lIGVuZXJneSBiaWxscyBhbmQgbG9va2luZyBmb3IgdGhvc2UgaG91c2Vob2xkcyB0aGF0IHN3aXRjaCBmcm9tIGdhcy9jb2FsIHRvIGVsZWN0cmljIG9ubHkuCgpTb2xhciBxdWVzdGlvbiBpcyBvbmx5IGFza2VkIGluIDIwMDksIDIwMTIsIDIwMTgsIGFuZCAyMDIxLiBFViBpcyBhc2tlZCBpbiAyMDEyLCAyMDE1LCAyMDE4LCBhbmQgMjAyMS4gU21hcnRwaG9uZSBiZWdpbnMgaW4gMjAxMy4gU2tpbGxzIHN0YXJ0cyBpbiAyMDExLgoKYGBge3IgVUsgVXB0YWtlIFJhdGVzLCBlY2hvPUZBTFNFfQojIFVLIHByb3BvcnRpb25zCnVrX3Byb3BzIDwtIFVLICU+JQogIGdyb3VwX2J5KHllYXIsIGRlY2lsZSkgJT4lCiAgc3VtbWFyaXNlKAogICAgbl90b3RhbCA9IG4oKSwKICAgIHNvbGFyX3Byb3AgPSBtZWFuKHNvbGFyMSAlaW4lIGMoInllcyAtIGZpdHRlZCIsICJZZXMgLSBmaXR0ZWQiKSwgbmEucm0gPSBUUlVFKSwKICAgIGV2X3Byb3AgPSBtZWFuKGNhcmZ1ZWwxICVpbiUgYygiRWxlY3RyaWMgLyBiYXR0ZXJ5IiwgImVsZWN0cmljIC8gYmF0dGVyeSIsICJIeWJyaWQgKHBldHJvbC9lbGVjdHJpYykiLCAiaHlicmlkIChwZXRyb2wvZWxlY3RyaWMpIiksIG5hLnJtID0gVFJVRSksCiAgICBzbWFydHBob25lX3Byb3AgPSBtZWFuKHNtYXJ0bW9iICVpbiUgYygiWWVzIiwgInllcyIpLCBuYS5ybSA9IFRSVUUgKSwKICAgIHNraWxsc19wcm9wID0gbWVhbihuZXRwdXNlICVpbiUgYygiRXZlcnkgZGF5IiwgImV2ZXJ5IGRheSIpIHwgbmV0cHVzZW5ldyAlaW4lIGMoIkV2ZXJ5IGRheSIsICJldmVyeSBkYXkiKSwgbmEucm0gPSBUUlVFKSwKICAgIGludGVybmV0X3Byb3AgPSBtZWFuKHBjbmV0ICVpbiUgYygieWVzIiwgIlllcyIpLCBuYS5ybSA9IFRSVUUpLAogICAgY29tbXV0ZV9wcm9wID0gbWVhbih3a3RydmZhciAlaW4lIGMoICJDeWNsZSIsICJCdXMvY29hY2giLCAiV2FsayIsICJUcmFpbiIsICJVbmRlcmdyb3VuZC9NZXRyby9UcmFtL0xpZ2h0IHJhaWx3YXkiLCAidW5kZXJncm91bmQvbWV0cm8vdHJhbS9saWdodCByYWlsd2F5IiwgIk1vdG9yY3ljbGUvbW9wZWQvc2Nvb3RlciIpIHwgd29ya3RyYXYgJWluJSBjKCJVbmRlcmdyb3VuZC9NZXRyby9UcmFtL0xpZ2h0IHJhaWx3YXkiLCAiVHJhaW4iLCAiY3ljbGUiLCAiV2FsayIsICJ1bmRlcmdyb3VuZC9tZXRyby90cmFtL2xpZ2h0IHJhaWx3YXkgKGlmIGVuZ2xhbmQvc2NvdGxhbmQvd2FsZXMpIiwgImJ1cy9jb2FjaCIsICJCdXMvY29hY2giLCAidHJhaW4iLCAidW5kZXJncm91bmQvbWV0cm8vdHJhbS9saWdodCByYWlsd2F5IiwgInVuZGVyZ3JvdW5kL21ldHJvL3RyYW0vbGlnaHQgcmFpbHdheSB7aWYgcmVnaW9uID0gZ2J9IiwgIk1vdG9yY3ljbGUvbW9wZWQvc2Nvb3RlciIpICwgbmEucm0gPSBUUlVFKSwKICAgIGZ1ZWxfc3dpdGNoX3Byb3AgPSBtZWFuKGdhc3BheSA9PSAiaW5hcHBsaWNhYmxlIiAmIGR1ZWxwYXkgPT0gImluYXBwbGljYWJsZSIsIG5hLnJtID0gVFJVRSkKICApICU+JQogIG11dGF0ZSgKICAgIHNvbGFyX3BlcmNlbnQgPSBzb2xhcl9wcm9wICogMTAwLAogICAgZXZfcGVyY2VudCA9IGV2X3Byb3AgKiAxMDAsCiAgICBzbWFydHBob25lX3BlcmNlbnQgPSBzbWFydHBob25lX3Byb3AgKiAxMDAsIAogICAgaW50ZXJuZXRfcGVyY2VudCA9IGludGVybmV0X3Byb3AgKiAxMDAsIAogICAgY29tbXV0ZV9wZXJjZW50ID0gY29tbXV0ZV9wcm9wICogMTAwLAogICAgc2tpbGxzX3BlcmNlbnQgPSBza2lsbHNfcHJvcCAqIDEwMCwgCiAgICBmdWVsX3N3aXRjaF9wZXJjZW50ID0gZnVlbF9zd2l0Y2hfcHJvcCAqIDEwMAogICkKCiMgQ29udmVydCB0byBsb25nIGZvcm1hdCB3aXRoIGFsbCB0ZWNobm9sb2dpZXMKdWtfcHJvcHNfbG9uZyA8LSB1a19wcm9wcyAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gYyhzb2xhcl9wZXJjZW50LCBldl9wZXJjZW50LCBzbWFydHBob25lX3BlcmNlbnQsIAogICAgICAgICAgICAgaW50ZXJuZXRfcGVyY2VudCwgc2tpbGxzX3BlcmNlbnQsIGNvbW11dGVfcGVyY2VudCwgZnVlbF9zd2l0Y2hfcGVyY2VudCksCiAgICBuYW1lc190byA9ICJ0ZWNobm9sb2d5IiwKICAgIHZhbHVlc190byA9ICJwZXJjZW50YWdlIgogICkgJT4lCiAgbXV0YXRlKHRlY2hub2xvZ3kgPSBmYWN0b3IodGVjaG5vbG9neSwgCiAgICBsZXZlbHMgPSBjKCJldl9wZXJjZW50IiwgInNvbGFyX3BlcmNlbnQiLCAic21hcnRwaG9uZV9wZXJjZW50IiwgCiAgICAgICAgICAgICAgICJpbnRlcm5ldF9wZXJjZW50IiwgInNraWxsc19wZXJjZW50IiwgImNvbW11dGVfcGVyY2VudCIsICJmdWVsX3N3aXRjaF9wZXJjZW50IiksCiAgICBsYWJlbHMgPSBjKCJFbGVjdHJpYyBWZWhpY2xlIiwgIlNvbGFyIFBhbmVscyIsICJTbWFydHBob25lIiwgCiAgICAgICAgICAgICAgICJJbnRlcm5ldCIsICJEaWdpdGFsIFNraWxscyIsICJTdXN0YWluYWJsZSBUcmFuc3BvcnQiLCAiQ2xlYW4gSGVhdGluZyBTd2l0Y2giKSkpCgpnZ3Bsb3QodWtfcHJvcHNfbG9uZywgYWVzKHggPSBkZWNpbGUsIHkgPSBwZXJjZW50YWdlLCBjb2xvciA9IHRlY2hub2xvZ3kpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgZmFjZXRfd3JhcCh+eWVhcikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicygKICAgIHRpdGxlID0gIlRlY2hub2xvZ3kgQWRvcHRpb24gYnkgSW5jb21lIERlY2lsZSBpbiBVSyIsCiAgICB4ID0gIkluY29tZSBEZWNpbGUiLAogICAgeSA9ICJQZXJjZW50YWdlIG9mIEhvdXNlaG9sZHMgKCUpIiwKICAgIGNvbG9yID0gIlRlY2hub2xvZ3kiCiAgKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDE6MTApICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgbGVnZW5kLmJveCA9ICJ2ZXJ0aWNhbCIsCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpCiAgKSArCiAgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAyKSkgIyBNYWtlcyBsZWdlbmQgbW9yZSBjb21wYWN0CgpnZ3Bsb3QodWtfcHJvcHNfbG9uZ1t1a19wcm9wc19sb25nJHBlcmNlbnRhZ2UgIT0gMCwgXSwgYWVzKHggPSB5ZWFyLCB5ID0gcGVyY2VudGFnZSwgY29sb3IgPSB0ZWNobm9sb2d5KSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIGZhY2V0X3dyYXAofmRlY2lsZSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicygKICAgIHRpdGxlID0gIlRlY2hub2xvZ3kgQWRvcHRpb24gT3ZlciBUaW1lIGJ5IEluY29tZSBEZWNpbGUgVUsiLAogICAgeCA9ICJZZWFyIiwKICAgIHkgPSAiUGVyY2VudGFnZSBvZiBIb3VzZWhvbGRzICglKSIsCiAgICBjb2xvciA9ICJUZWNobm9sb2d5IgogICkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkKICApICsKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQobnJvdyA9IDIpKQoKIyBBbHRlcm5hdGl2ZSB2aXN1YWxpemF0aW9uOiBGYWNldGVkIHBsb3QgZm9yIGNsZWFyZXIgdmlld2luZwpnZ3Bsb3QodWtfcHJvcHNfbG9uZywgYWVzKHggPSBkZWNpbGUsIHkgPSBwZXJjZW50YWdlKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJncmV5NzAiKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSB0ZWNobm9sb2d5KSwgc2l6ZSA9IDMpICsKICBmYWNldF9ncmlkKHRlY2hub2xvZ3kgfiB5ZWFyKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKAogICAgdGl0bGUgPSAiVGVjaG5vbG9neSBBZG9wdGlvbiBieSBJbmNvbWUgRGVjaWxlIGluIFVLIiwKICAgIHggPSAiSW5jb21lIERlY2lsZSIsCiAgICB5ID0gIlBlcmNlbnRhZ2Ugb2YgSG91c2Vob2xkcyAoJSkiCiAgKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgyLCAxMCwgMikpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLAogICAgcGFuZWwuc3BhY2luZy55ID0gdW5pdCgxLCAibGluZXMiKQogICkKYGBgCgojIyMgR2VybWFueSBVcHRha2UgUmF0ZXMKCkZvciBHZXJtYW55IEkgaGF2ZSBpbmZvcm1hdGlvbiBvbiBzb2xhciwgRVYsIHJldHJvZml0dGluZywgc21hcnRwaG9uZSwgaW50ZXJuZXQuCgpFViBvbmx5IGV4aXN0cyBpbiAyMDE1IGFuZCAyMDIwLiAobm90ZSBpdCBpcyBmdWxsIEVWIG9yIGJpb2RpZXNlbCwgbm8gaHlicmlkIGNhdGVnb3J5KSBSZXRyb2ZpdHRpbmcgaXMgYXNrZWQgZnJvbSAyMDEwIC0gMjAxNSwgYW5kIDIwMTkgU21hcnRwaG9uZQoKYGBge3IgREVVIFVwdGFrZSBSYXRlcywgZWNobz1GQUxTRX0KCmRldV9wcm9wcyA8LSBERVUgJT4lCiAgZ3JvdXBfYnkoc3llYXIsIGRlY2lsZSkgJT4lCiAgc3VtbWFyaXNlKAogICAgbl90b3RhbCA9IG4oKSwKICAgIGh5YnJpZF9wcm9wID0gc3VtKGhsaTAxMjEgPT0gMSB8IGhsaTAxMjMgPT0gMSB8IGhsaTAxMjQgPT0gMSB8IAogICAgICAgICAgICAgICAgICAgICBobGkwMTE0ID09IDEgfCBobGkwMTE1ID09IDEgfCBobGkwMTE2ID09IDEgfCBobGkwMTE3ID09IDEsIAogICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpIC8gbigpLAogICAgc29sYXJfcHJvcCA9IHN1bShoZ2VxcHNvbCA9PSAxLCBuYS5ybSA9IFRSVUUpIC8gbigpLAogICAgcmVub3ZhdGlvbl9wcm9wID0gc3VtKGhnY29uZGl0ID09IDIgfCBoZ2NvbmRpdCA9PSAzLCBuYS5ybSA9IFRSVUUpIC9uKCksCiAgICBzbWFydHBob25lX3Byb3AgPSBzdW0oaGdlcXB0ZWwgPT0gMSwgbmEucm0gPSBUUlVFKSAvIG4oKSwKICAgIGludGVybmV0X25ldyA9IHN1bShobGYwMTY5X2ggPT0gMSAsIG5hLnJtID0gVFJVRSkgLyBuKCkKICApICU+JQogIGdyb3VwX2J5KGRlY2lsZSkgJT4lCiAgYXJyYW5nZShzeWVhcikgJT4lCiAgbXV0YXRlKAogICAgaW50ZXJuZXRfcHJvcCA9IHBtaW4oY3Vtc3VtKGludGVybmV0X25ldyksIDEpLAogICAgc21hcnRwaG9uZV9wcm9wID0gaWZfZWxzZShzeWVhciA+IDIwMTUsIDEsIHNtYXJ0cGhvbmVfcHJvcCkKICApICU+JQogIHNlbGVjdCgtaW50ZXJuZXRfbmV3KSAlPiUKICBtdXRhdGUoCiAgICBoeWJyaWRfcGVyY2VudCA9IGh5YnJpZF9wcm9wICogMTAwLAogICAgc29sYXJfcGVyY2VudCA9IHNvbGFyX3Byb3AgKiAxMDAsIAogICAgcmVub3ZhdGlvbl9wZXJjZW50ID0gcmVub3ZhdGlvbl9wcm9wICogMTAwLCAKICAgIHNtYXJ0cGhvbmVfcGVyY2VudCA9IHNtYXJ0cGhvbmVfcHJvcCAqIDEwMCwKICAgIGludGVybmV0X3BlcmNlbnQgPSBpbnRlcm5ldF9wcm9wICogMTAwCiAgKQoKCmRldV9wcm9wc19sb25nIDwtIGRldV9wcm9wcyAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gYyhoeWJyaWRfcGVyY2VudCwgc29sYXJfcGVyY2VudCwgcmVub3ZhdGlvbl9wZXJjZW50LCBzbWFydHBob25lX3BlcmNlbnQsIGludGVybmV0X3BlcmNlbnQpLAogICAgbmFtZXNfdG8gPSAidGVjaG5vbG9neSIsCiAgICB2YWx1ZXNfdG8gPSAicGVyY2VudGFnZSIKICApICU+JQogIG11dGF0ZSh0ZWNobm9sb2d5ID0gZmFjdG9yKHRlY2hub2xvZ3ksIAogICAgbGV2ZWxzID0gYygiaHlicmlkX3BlcmNlbnQiLCAic29sYXJfcGVyY2VudCIsICJyZW5vdmF0aW9uX3BlcmNlbnQiLCAic21hcnRwaG9uZV9wZXJjZW50IiwgImludGVybmV0X3BlcmNlbnQiKSwKICAgIGxhYmVscyA9IGMoIkh5YnJpZC9FViIsICJTb2xhciBQYW5lbHMiLCAiSG9tZSBSZW5vdmF0aW9ucyIsICJPd25zIGEgU21hcnRwaG9uZSIsICJJbnRlcm5ldCBhY2Nlc3MiKSkpCgpnZ3Bsb3QoZGV1X3Byb3BzX2xvbmcsIGFlcyh4ID0gZGVjaWxlLCB5ID0gcGVyY2VudGFnZSwgY29sb3IgPSB0ZWNobm9sb2d5KSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIGZhY2V0X3dyYXAofnN5ZWFyKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKAogICAgdGl0bGUgPSAiVGVjaG5vbG9neSBBZG9wdGlvbiBieSBJbmNvbWUgRGVjaWxlIGluIEdlcm1hbnkiLAogICAgeCA9ICJJbmNvbWUgRGVjaWxlIiwKICAgIHkgPSAiUGVyY2VudGFnZSBvZiBIb3VzZWhvbGRzICglKSIsCiAgICBjb2xvciA9ICJUZWNobm9sb2d5IgogICkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAxOjEwKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCgpnZ3Bsb3QoZGV1X3Byb3BzX2xvbmdbZGV1X3Byb3BzX2xvbmckcGVyY2VudGFnZSAhPSAwLCBdLCBhZXMoeCA9IHN5ZWFyLCB5ID0gcGVyY2VudGFnZSwgY29sb3IgPSB0ZWNobm9sb2d5KSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIGZhY2V0X3dyYXAofmRlY2lsZSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicygKICAgIHRpdGxlID0gIlRlY2hub2xvZ3kgQWRvcHRpb24gT3ZlciBUaW1lIGJ5IEluY29tZSBEZWNpbGUgR2VybWFueSIsCiAgICB4ID0gIlllYXIiLAogICAgeSA9ICJQZXJjZW50YWdlIG9mIEhvdXNlaG9sZHMgKCUpIiwKICAgIGNvbG9yID0gIlRlY2hub2xvZ3kiCiAgKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGxlZ2VuZC5ib3ggPSAidmVydGljYWwiLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQogICkgKwogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChucm93ID0gMikpCgpgYGAKCiMjIyBDb21iaW5lZCBVcHRha2UgUmF0ZXMKTm90IGFsbCB0ZWNobm9sb2dpZXMgaW4gZWFjaCBjb3VudHJ5IGhhdmUgdGhlIHNhbWUgeWVhciBvZiBzdGFydCBhbmQgZW5kIGRhdGEuIEkgbm93IGdldCBkYXRhIGFzIGNsb3NlIHRvIDIwMTUgc3RhcnQgYW5kIDIwMjEgZW5kIGFzIHBvc3NpYmxlLiBMb29rIGF0IHllYXIgcmFuZ2VzIGF2YWlsYWJsZSBmb3IgdXB0YWtlIHJhdGVzIGZvciBlYWNoIGNvdW50cnkgYW5kIHRlY2hub2xvZ3kgYXQgZGVjaWxlIGxldmVsLiAKCmBgYHtyIGNvbWJpbmVkIHVwdGFrZSByYXRlcywgZWNobz1GQUxTRX0KCiMgQ2FsY3VsYXRlIHVwdGFrZSByYXRlcyBmb3IgVVMKdXNfdXB0YWtlX3JhdGVzIDwtIG1hcF9kZih1bmlxdWUodXNfcHJvcHNfbG9uZyR0ZWNobm9sb2d5KSwgZnVuY3Rpb24odGVjaCkgewogIHVzX3Byb3BzX2xvbmcgJT4lCiAgICBmaWx0ZXIoCiAgICAgIHRlY2hub2xvZ3kgPT0gdGVjaCwKICAgICAgeWVhciAlaW4lIGMoMjAxNSwgMjAyMSkKICAgICkgJT4lCiAgICBzZWxlY3QoeWVhciwgZGVjaWxlLCB0ZWNobm9sb2d5LCBwZXJjZW50YWdlKSAlPiUKICAgIHBpdm90X3dpZGVyKAogICAgICBuYW1lc19mcm9tID0geWVhciwKICAgICAgdmFsdWVzX2Zyb20gPSBwZXJjZW50YWdlCiAgICApICU+JQogICAgbXV0YXRlKAogICAgICBzdGFydF95ZWFyID0gMjAxNSwKICAgICAgdXB0YWtlX3JhdGUgPSAhIXN5bShhcy5jaGFyYWN0ZXIoMjAyMSkpIC0gISFzeW0oYXMuY2hhcmFjdGVyKDIwMTUpKSwKICAgICAgY291bnRyeSA9ICJVUyIKICAgICkKfSkKCiMgQ2FsY3VsYXRlIHVwdGFrZSByYXRlcyBmb3IgVUsKdWtfdXB0YWtlX3JhdGVzIDwtIG1hcF9kZih1bmlxdWUodWtfcHJvcHNfbG9uZyR0ZWNobm9sb2d5KSwgZnVuY3Rpb24odGVjaCkgewogICMgU2V0IHN0YXJ0IHllYXIgYmFzZWQgb24gdGVjaG5vbG9neQogIHN0YXJ0X3llYXIgPC0gaWYodGVjaCA9PSAiU29sYXIgUGFuZWxzIikgewogICAgMjAxMgogIH0gZWxzZSB7CiAgICAyMDE1CiAgfQogIAogICMgU2V0IGVuZCB5ZWFyIGJhc2VkIG9uIHRlY2hub2xvZ3kKICBlbmRfeWVhciA8LSBpZih0ZWNoID09ICJEaWdpdGFsIFNraWxscyIpIHsKICAgIDIwMTkKICB9IGVsc2UgewogICAgMjAyMQogIH0KICAKICB1a19wcm9wc19sb25nICU+JQogICAgZmlsdGVyKAogICAgICB0ZWNobm9sb2d5ID09IHRlY2gsCiAgICAgIHllYXIgJWluJSBjKHN0YXJ0X3llYXIsIGVuZF95ZWFyKQogICAgKSAlPiUKICAgIHNlbGVjdCh5ZWFyLCBkZWNpbGUsIHRlY2hub2xvZ3ksIHBlcmNlbnRhZ2UpICU+JQogICAgcGl2b3Rfd2lkZXIoCiAgICAgIG5hbWVzX2Zyb20gPSB5ZWFyLAogICAgICB2YWx1ZXNfZnJvbSA9IHBlcmNlbnRhZ2UKICAgICkgJT4lCiAgICBtdXRhdGUoCiAgICAgIHN0YXJ0X3llYXIgPSBzdGFydF95ZWFyLAogICAgICBlbmRfeWVhciA9IGVuZF95ZWFyLAogICAgICB1cHRha2VfcmF0ZSA9ICEhc3ltKGFzLmNoYXJhY3RlcihlbmRfeWVhcikpIC0gISFzeW0oYXMuY2hhcmFjdGVyKHN0YXJ0X3llYXIpKSwKICAgICAgY291bnRyeSA9ICJVSyIKICAgICkKfSkKCiMgQ2FsY3VsYXRlIHVwdGFrZSByYXRlcyBmb3IgR2VybWFueQpkZXVfdXB0YWtlX3JhdGVzIDwtIG1hcF9kZih1bmlxdWUoZGV1X3Byb3BzX2xvbmckdGVjaG5vbG9neSksIGZ1bmN0aW9uKHRlY2gpIHsKICAjIFNldCBzdGFydCB5ZWFyIGJhc2VkIG9uIHRlY2hub2xvZ3kKICBzdGFydF95ZWFyIDwtIGlmKHRlY2ggPT0gIkh5YnJpZC9FViIpIHsKICAgIDIwMTUKICB9IGVsc2UgewogICAgZmluZF9maXJzdF95ZWFyKGRldV9wcm9wc19sb25nICU+JSByZW5hbWUoeWVhciA9IHN5ZWFyKSwgdGVjaCwgInllYXIiKQogIH0KICAKICAjIFNldCBlbmQgeWVhciBiYXNlZCBvbiB0ZWNobm9sb2d5CiAgZW5kX3llYXIgPC0gY2FzZV93aGVuKAogICAgdGVjaCA9PSAiSG9tZSBSZW5vdmF0aW9uIiB+IDIwMTksCiAgICB0ZWNoID09ICJIeWJyaWQvRVYiIH4gMjAyMCwKICAgIFRSVUUgfiAyMDIxCiAgKQogIAogIGRldV9wcm9wc19sb25nICU+JQogICAgZmlsdGVyKAogICAgICB0ZWNobm9sb2d5ID09IHRlY2gsCiAgICAgIHN5ZWFyICVpbiUgYyhzdGFydF95ZWFyLCBlbmRfeWVhcikKICAgICkgJT4lCiAgICBzZWxlY3Qoc3llYXIsIGRlY2lsZSwgdGVjaG5vbG9neSwgcGVyY2VudGFnZSkgJT4lCiAgICBwaXZvdF93aWRlcigKICAgICAgbmFtZXNfZnJvbSA9IHN5ZWFyLAogICAgICB2YWx1ZXNfZnJvbSA9IHBlcmNlbnRhZ2UKICAgICkgJT4lCiAgICBtdXRhdGUoCiAgICAgIHN0YXJ0X3llYXIgPSBzdGFydF95ZWFyLAogICAgICBlbmRfeWVhciA9IGVuZF95ZWFyLAogICAgICB1cHRha2VfcmF0ZSA9ICEhc3ltKGFzLmNoYXJhY3RlcihlbmRfeWVhcikpIC0gISFzeW0oYXMuY2hhcmFjdGVyKHN0YXJ0X3llYXIpKSwKICAgICAgY291bnRyeSA9ICJHZXJtYW55IgogICAgKQp9KQojIENvbWJpbmUgYWxsIGRhdGFzZXRzCmFsbF91cHRha2VfcmF0ZXMgPC0gYmluZF9yb3dzKHVzX3VwdGFrZV9yYXRlcywgdWtfdXB0YWtlX3JhdGVzLCBkZXVfdXB0YWtlX3JhdGVzKQoKIyBQcmludCBzdW1tYXJ5IG9mIHN0YXJ0IHllYXJzIHVzZWQKcHJpbnQoIlN0YXJ0IHllYXJzIHVzZWQgZm9yIGVhY2ggdGVjaG5vbG9neSBieSBjb3VudHJ5OiIpCmFsbF91cHRha2VfcmF0ZXMgJT4lCiAgZGlzdGluY3QoY291bnRyeSwgdGVjaG5vbG9neSwgc3RhcnRfeWVhcikgJT4lCiAgYXJyYW5nZShjb3VudHJ5LCB0ZWNobm9sb2d5KSAlPiUKICBwcmludChuID0gSW5mKQoKIyBDcmVhdGUgaGVhdG1hcApoZWF0bWFwX2FsbCA8LSBnZ3Bsb3QoYWxsX3VwdGFrZV9yYXRlcywgCiAgYWVzKHggPSBmYWN0b3IoZGVjaWxlKSwgCiAgICAgIHkgPSBwYXN0ZTAodGVjaG5vbG9neSwgIiAoIiwgc3RhcnRfeWVhciwgIi0iLCBpZmVsc2UoY291bnRyeSA9PSAiR2VybWFueSIgJiB0ZWNobm9sb2d5ID09ICJIb21lIFJlbm92YXRpb24iLCAiMjAxOSIsICIyMDIxIiksICIpIiksIAogICAgICBmaWxsID0gdXB0YWtlX3JhdGUpKSArCiAgZ2VvbV90aWxlKCkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKAogICAgbG93ID0gInJlZCIsCiAgICBtaWQgPSAid2hpdGUiLAogICAgaGlnaCA9ICJkYXJrZ3JlZW4iLAogICAgbWlkcG9pbnQgPSAwLAogICAgbGltaXRzID0gYygtNSwgNSksCiAgICBvb2IgPSBzY2FsZXM6OnNxdWlzaAogICkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgZmFjZXRfd3JhcCh+Y291bnRyeSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJUZWNobm9sb2d5IFVwdGFrZSBSYXRlcyBieSBJbmNvbWUgRGVjaWxlIiwKICAgIHN1YnRpdGxlID0gIlBlcmNlbnRhZ2UgUG9pbnQgQ2hhbmdlIGluIEFkb3B0aW9uIChDYXBwZWQgYXQgwrE1IHBlcmNlbnRhZ2UgcG9pbnRzKSIsCiAgICB4ID0gIkluY29tZSBEZWNpbGUiLAogICAgeSA9IE5VTEwsCiAgICBmaWxsID0gIlBlcmNlbnRhZ2VcblBvaW50IENoYW5nZSIKICApICsKICB0aGVtZSgKICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSksCiAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiCiAgKQoKIyBDcmVhdGUgYm94cGxvdApib3hwbG90X2FsbCA8LSBnZ3Bsb3QoYWxsX3VwdGFrZV9yYXRlcywgCiAgYWVzKHkgPSBwYXN0ZTAodGVjaG5vbG9neSwgIiAoIiwgc3RhcnRfeWVhciwgIi0iLCBpZmVsc2UoY291bnRyeSA9PSAiR2VybWFueSIgJiB0ZWNobm9sb2d5ID09ICJIb21lIFJlbm92YXRpb25zIiwgIjIwMTkiLCAiMjAyMSIpLCAiKSIpLCAKICAgICAgZmlsbCA9IGNvdW50cnkpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgY29sb3IgPSAiZ3JleTgwIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogIGdlb21fYm94cGxvdChhZXMoeCA9IHVwdGFrZV9yYXRlKSwgd2lkdGggPSAwLjcsIGFscGhhID0gMC43LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC44KSkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJUZWNobm9sb2d5IFVwdGFrZSBEaXN0cmlidXRpb24gYnkgVHlwZSBhbmQgQ291bnRyeSIsCiAgICBzdWJ0aXRsZSA9ICJCb3hwbG90cyBzaG93IGRpc3RyaWJ1dGlvbiBhY3Jvc3MgaW5jb21lIGRlY2lsZXMiLAogICAgeCA9ICJQZXJjZW50YWdlIFBvaW50IENoYW5nZSIsCiAgICB5ID0gTlVMTCwKICAgIGZpbGwgPSAiQ291bnRyeSIKICApICsKICB0aGVtZSgKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIgogICkKCiMgRGlzcGxheSBwbG90cwpoZWF0bWFwX2FsbApib3hwbG90X2FsbApgYGAKClRoZXJlIGFyZSB0d28gb3V0bGllciB0ZWNobm9sb2dpZXMgZm9yIHVwdGFrZSByYXRlcy4gVGhlIGZpcnN0IGlzIFN1c3RhaW5hYmxlIFRyYW5zaXQgaW4gdGhlIFVLLiBVSyBjb21tdXRlIChzdXN0YWluYWJsZSB0cmFuc3BvcnQpIG9ubHkgc2hvd3MgY29tbXV0aW5nIHBhdHRlcm5zIGZvciB0aG9zZSB3aG8gd29yaywgc28gcG90ZW50aWFsbHkgaGlkZXMgc2lnbmlmaWNhbnQgY29tbXV0aW5nIHByZWZlcmVuY2VzLCBwYXJ0aWN1bGFybHkgZm9yIHRob3NlIG91dCBvZiB3b3JrIG9yIGpvYiBzZWVraW5nIGFuZCBpcyBiZWluZyBjb21wYXJlZCBhZ2FpbnN0IENPVklEIHNvIGxlc3MgcGVvcGxlIHdlcmUgY29tbXV0aW5nIHRvIHdvcmsgaW4gMjAyMSwgbm8gbWF0dGVyIHRoZWlyIG1ldGhvZC4gVGhlIHNlY29uZCBpcyBob21lIHJlbm92YXRpb25zIGluIEdlcm1hbnkuIElmIGkgY2FuZ2UgdGhlIHllYXIgdG8gbGF0ZXIsIHRoZSBmaWd1cmUgZG9lcyBnbyB1cCwgYnV0IDIwMTAgc2hvd3MgYSByZW5vdmF0aW9uIGJvb20gdGhhdCBpcyBsb3N0IGluIGxhdGVyIHllYXJzLgoKRm9yIGZ1biwgSSdtIGFsc28gbG9va2luZyBhdCBVUyBzdGF0ZSB2YXJpYXRpb24sIGJ1dCB0aGlzIGlzIGZvciBQaEQsIHBsZWFzZSBpZ25vcmUgaW4gbWVldGluZy4KCmBgYHtyIFVTIFJlZ2lvbmFsIEFkb3B0aW9uLCBpbmNsdWRlPUZBTFNFfQojIENhbGN1bGF0ZSBzdGF0ZSBhZG9wdGlvbiByYXRlcwpzdGF0ZV9hZG9wdGlvbiA8LSBVUyAlPiUKICBncm91cF9ieSh5ZWFyLCBoaF9zdGF0ZSkgJT4lCiAgc3VtbWFyaXNlKAogICAgbl90b3RhbCA9IG4oKSwKICAgIHNtYXJ0cGhvbmVfcHJvcCA9IG1lYW4oc21hcnRwaG9uZSA9PSAxLCBuYS5ybSA9IFRSVUUpLAogICAgaHlicmlkX3Byb3AgPSBtZWFuKGh5YnJpZCA9PSAxLCBuYS5ybSA9IFRSVUUpLAogICAgc29sYXJfcHJvcCA9IG1lYW4oaGVhdF9tZXRob2QgPT0gNiwgbmEucm0gPSBUUlVFKSwKICAgIGludGVybmV0X3Byb3AgPSBtZWFuKGNvbXB1dGVyID09IDEsIG5hLnJtID0gVFJVRSksCiAgICByZXBhaXJzX3Byb3AgPSBtZWFuKGhoX3JlcGFpciA+IDEsIG5hLnJtID0gVFJVRSksCiAgICBza2lsbHNfcHJvcCA9IG1lYW4oaW50ZXJuZXQgPT0gMSwgbmEucm0gPSBUUlVFKSwKICAgIGZ1ZWxfc3dpdGNoX3Byb3AgPSBtZWFuKHN3aXRjaGVkX3RvX2VsZWN0cmljIHwgc3dpdGNoZWRfdG9fc29sYXIsIG5hLnJtID0gVFJVRSkKICApICU+JQogIG11dGF0ZSgKICAgIHNtYXJ0cGhvbmVfcGVyY2VudCA9IHNtYXJ0cGhvbmVfcHJvcCAqIDEwMCwKICAgIGh5YnJpZF9wZXJjZW50ID0gaHlicmlkX3Byb3AgKiAxMDAsCiAgICBzb2xhcl9wZXJjZW50ID0gc29sYXJfcHJvcCAqIDEwMCwKICAgIGludGVybmV0X3BlcmNlbnQgPSBpbnRlcm5ldF9wcm9wICogMTAwLAogICAgcmVwYWlyc19wZXJjZW50ID0gcmVwYWlyc19wcm9wICogMTAwLAogICAgc2tpbGxzX3BlcmNlbnQgPSBza2lsbHNfcHJvcCAqIDEwMCwKICAgIGZ1ZWxfc3dpdGNoX3BlcmNlbnQgPSBmdWVsX3N3aXRjaF9wcm9wICogMTAwCiAgKQoKIyBDb252ZXJ0IHRvIGxvbmcgZm9ybWF0CnN0YXRlX2Fkb3B0aW9uX2xvbmcgPC0gc3RhdGVfYWRvcHRpb24gJT4lCiAgcGl2b3RfbG9uZ2VyKAogICAgY29scyA9IGVuZHNfd2l0aCgicGVyY2VudCIpLAogICAgbmFtZXNfdG8gPSAidGVjaG5vbG9neSIsCiAgICB2YWx1ZXNfdG8gPSAicGVyY2VudGFnZSIKICApICU+JQogIG11dGF0ZSh0ZWNobm9sb2d5ID0gZmFjdG9yKHRlY2hub2xvZ3ksCiAgICBsZXZlbHMgPSBjKCJzbWFydHBob25lX3BlcmNlbnQiLCAiaHlicmlkX3BlcmNlbnQiLCAic29sYXJfcGVyY2VudCIsCiAgICAgICAgICAgICAgICJpbnRlcm5ldF9wZXJjZW50IiwgInJlcGFpcnNfcGVyY2VudCIsICJza2lsbHNfcGVyY2VudCIsCiAgICAgICAgICAgICAgICJmdWVsX3N3aXRjaF9wZXJjZW50IiksCiAgICBsYWJlbHMgPSBjKCJTbWFydHBob25lIiwgIkh5YnJpZC9FViIsICJTb2xhciBQYW5lbHMiLAogICAgICAgICAgICAgICAiSW50ZXJuZXQiLCAiSG9tZSBSZXBhaXJzIiwgIkRpZ2l0YWwgU2tpbGxzIiwKICAgICAgICAgICAgICAgIkNsZWFuIEhlYXRpbmcgU3dpdGNoIikKICApKQoKIyBDYWxjdWxhdGUgc3RhdGUgZ3Jvd3RoICgyMDE1LTIwMjApCnN0YXRlX2dyb3d0aCA8LSBzdGF0ZV9hZG9wdGlvbl9sb25nICU+JQogIGZpbHRlcih5ZWFyICVpbiUgYygyMDE1LCAyMDIxKSkgJT4lCiAgc2VsZWN0KHllYXIsIGhoX3N0YXRlLCB0ZWNobm9sb2d5LCBwZXJjZW50YWdlKSAlPiUKICBwaXZvdF93aWRlcigKICAgIG5hbWVzX2Zyb20gPSB5ZWFyLAogICAgdmFsdWVzX2Zyb20gPSBwZXJjZW50YWdlLAogICAgbmFtZXNfcHJlZml4ID0gInllYXJfIgogICkgJT4lCiAgbXV0YXRlKAogICAgZ3Jvd3RoX3JhdGUgPSBwbWF4KHllYXJfMjAyMSAtIHllYXJfMjAxNSwgMCkKICApCgojIENyZWF0ZSBoZWF0bWFwIG9mIHN0YXRlIGdyb3d0aCAodG9wIDIwIHN0YXRlcyBieSBhdmVyYWdlIGdyb3d0aCkKdG9wX3N0YXRlcyA8LSBzdGF0ZV9ncm93dGggJT4lCiAgZ3JvdXBfYnkoaGhfc3RhdGUpICU+JQogIHN1bW1hcmlzZShtZWFuX2dyb3d0aCA9IG1lYW4oZ3Jvd3RoX3JhdGUsIG5hLnJtID0gVFJVRSkpICU+JQogIGFycmFuZ2UoZGVzYyhtZWFuX2dyb3d0aCkpICU+JQogIGhlYWQoMjApICU+JQogIHB1bGwoaGhfc3RhdGUpCgpnZ3Bsb3Qoc3RhdGVfZ3Jvd3RoICU+JSBmaWx0ZXIoaGhfc3RhdGUgJWluJSB0b3Bfc3RhdGVzKSwKICAgICAgIGFlcyh5ID0gcmVvcmRlcihoaF9zdGF0ZSwgZ3Jvd3RoX3JhdGUpLCB4ID0gdGVjaG5vbG9neSwgZmlsbCA9IGdyb3d0aF9yYXRlKSkgKwogIGdlb21fdGlsZSgpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJ3aGl0ZSIsIGhpZ2ggPSAiZGFya2dyZWVuIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicygKICAgIHRpdGxlID0gIlRlY2hub2xvZ3kgQWRvcHRpb24gR3Jvd3RoIGJ5IFN0YXRlICgyMDE1LTIwMjApIiwKICAgIHN1YnRpdGxlID0gIlRvcCAyMCBzdGF0ZXMgYnkgYXZlcmFnZSBncm93dGggcmF0ZSBhY3Jvc3MgdGVjaG5vbG9naWVzIiwKICAgIHggPSAiVGVjaG5vbG9neSIsCiAgICB5ID0gIlN0YXRlIiwKICAgIGZpbGwgPSAiR3Jvd3RoIFJhdGUgKCUpIgogICkgKwogIHRoZW1lKAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwKICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkKICApCgojIENyZWF0ZSBib3hwbG90IG9mIHN0YXRlIGRpc3RyaWJ1dGlvbnMgYnkgdGVjaG5vbG9neQpnZ3Bsb3Qoc3RhdGVfZ3Jvd3RoLCBhZXMoeSA9IHJlb3JkZXIodGVjaG5vbG9neSwgZ3Jvd3RoX3JhdGUsIEZVTiA9IG1lZGlhbikpKSArCiAgZ2VvbV9ib3hwbG90KGFlcyh4ID0gZ3Jvd3RoX3JhdGUpLCBmaWxsID0gImxpZ2h0Z3JlZW4iLCBhbHBoYSA9IDAuNSkgKwogIGdlb21faml0dGVyKGFlcyh4ID0gZ3Jvd3RoX3JhdGUpLCBoZWlnaHQgPSAwLjIsIGFscGhhID0gMC40KSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKAogICAgdGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIFRlY2hub2xvZ3kgQWRvcHRpb24gR3Jvd3RoIEFjcm9zcyBTdGF0ZXMgKDIwMTUtMjAyMCkiLAogICAgc3VidGl0bGUgPSAiRWFjaCBwb2ludCByZXByZXNlbnRzIGEgc3RhdGUiLAogICAgeCA9ICJQZXJjZW50YWdlIFBvaW50IEdyb3d0aCIsCiAgICB5ID0gTlVMTAogICkKCiMgQ2FsY3VsYXRlIHN1bW1hcnkgc3RhdGlzdGljcyBmb3IgZWFjaCBzdGF0ZQpzdGF0ZV9zdW1tYXJ5IDwtIHN0YXRlX2dyb3d0aCAlPiUKICBncm91cF9ieShoaF9zdGF0ZSkgJT4lCiAgc3VtbWFyaXNlKAogICAgbWVhbl9ncm93dGggPSBtZWFuKGdyb3d0aF9yYXRlLCBuYS5ybSA9IFRSVUUpLAogICAgbWF4X2dyb3d0aCA9IG1heChncm93dGhfcmF0ZSwgbmEucm0gPSBUUlVFKSwKICAgIHRvcF90ZWNobm9sb2d5ID0gdGVjaG5vbG9neVt3aGljaC5tYXgoZ3Jvd3RoX3JhdGUpXSwKICAgIG5fdGVjaG5vbG9naWVzID0gc3VtKGdyb3d0aF9yYXRlID4gMCwgbmEucm0gPSBUUlVFKQogICkgJT4lCiAgYXJyYW5nZShkZXNjKG1lYW5fZ3Jvd3RoKSkKCnByaW50KCJUb3AgMTAgU3RhdGVzIGJ5IEF2ZXJhZ2UgR3Jvd3RoIFJhdGU6IikKcHJpbnQoaGVhZChzdGF0ZV9zdW1tYXJ5LCAxMCkpCgpgYGAKCiMjIFN0ZXAgMjogQmFzZWxpbmUgTW9kZWwKCkluIHRoZSBiYXNlbGluZSBtb2RlbCBJIGFzc3VtZSBubyB0YXJnZXRlZCBwb2xpY3kgdG8gY2hhbmdlIGRpc3RyaWJ1dGlvbiAoaS5lLiAzJSBmb3IgMTB0aCBkZWNpbGUgdnMgMTUlIGZvciAxc3QgaW4gMjAyMCB3aXRoIGEgY29uc3RhbnQgZ3Jvd3RoIHByb2plY3Rpb24gdG8gMjA1MCkuIE1vZGVsIGFpbXMgdG8gcmVhY2ggZXhvZ2Vub3VzbHkgZ292ZXJubWVudCBwcm92aWRlZCBkaWZmdXNpb24gdGFyZ2V0IGZvciBlYWNoIHRlY2hub2xvZ3kgKGUuZy40MCUgZm9yIGhvdXNpbmcgcmV0cm9maXQgdnMgNjAlIGZvciBFVnMpLiAKCiMjIyBVLlMuIEJhc2VsaW5lCgpgYGB7ciBVUyBCYXNlbGluZSwgZWNobz1GQUxTRX0KIyBDb252ZXJ0IGRhdGEgZnJhbWUgdG8gdGliYmxlCnVzX3Byb3BzIDwtIGFzX3RpYmJsZSh1c19wcm9wcykKCiMgRnVuY3Rpb24gdG8gZml0IGFuZCBmb3JlY2FzdCB0ZWNobm9sb2d5IGRpZmZ1c2lvbgpmb3JlY2FzdF9kaWZmdXNpb24gPC0gZnVuY3Rpb24oZGF0YSwgdGVjaF9jb2wsIG1heF9hZG9wdGlvbiA9IDEwMCwgZm9yZWNhc3RfeWVhciA9IDIwNTApIHsKICAjIENyZWF0ZSBtb2RlbCBkYXRhCiAgbW9kZWxfZGF0YSA8LSB0aWJibGUoCiAgICB5ZWFyID0gZGF0YSR5ZWFyLAogICAgYWRvcHRpb24gPSBkYXRhW1t0ZWNoX2NvbF1dCiAgKSAlPiUKICAgIGFycmFuZ2UoeWVhcikgJT4lCiAgICBmaWx0ZXIoIWlzLm5hKGFkb3B0aW9uKSkKICAKICAjIEZpdCBsb2dpc3RpYyBjdXJ2ZQogIHRyeUNhdGNoKHsKICAgICMgU2V0IGNvbnRyb2wgcGFyYW1ldGVycyBkaWZmZXJlbnRseQogICAgbW9kZWwgPC0gZHJtKGFkb3B0aW9uIH4geWVhciwgCiAgICAgICAgICAgICAgICAgZGF0YSA9IG1vZGVsX2RhdGEsCiAgICAgICAgICAgICAgICAgZmN0ID0gTC40KCksICMgNC1wYXJhbWV0ZXIgbG9naXN0aWMgZnVuY3Rpb24KICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChtYXhpdGVyID0gNTAwLCBzdGVwc2l6ZSA9IDAuMSkpCiAgICAKICAgICMgR2VuZXJhdGUgZnV0dXJlIHllYXJzCiAgICBmdXR1cmVfeWVhcnMgPC0gc2VxKG1pbihtb2RlbF9kYXRhJHllYXIpLCBmb3JlY2FzdF95ZWFyLCBieSA9IDEpCiAgICAKICAgICMgTWFrZSBwcmVkaWN0aW9ucwogICAgcHJlZGljdGlvbnMgPC0gdGliYmxlKAogICAgICB5ZWFyID0gZnV0dXJlX3llYXJzLAogICAgICBwcmVkaWN0ZWRfYWRvcHRpb24gPSBwcmVkaWN0KG1vZGVsLCBkYXRhLmZyYW1lKHllYXIgPSBmdXR1cmVfeWVhcnMpKQogICAgKQogICAgCiAgICAjIFRyeSB0byBhZGQgY29uZmlkZW5jZSBpbnRlcnZhbHMKICAgIHRyeUNhdGNoKHsKICAgICAgY2kgPC0gcHJlZGljdChtb2RlbCwgZGF0YS5mcmFtZSh5ZWFyID0gZnV0dXJlX3llYXJzKSwgaW50ZXJ2YWwgPSAiY29uZmlkZW5jZSIpCiAgICAgIHByZWRpY3Rpb25zJGxvd2VyX2NpIDwtIGNpWywyXQogICAgICBwcmVkaWN0aW9ucyR1cHBlcl9jaSA8LSBjaVssM10KICAgIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgTlVMTCkKICAgIAogICAgbGlzdCgKICAgICAgcHJlZGljdGlvbnMgPSBwcmVkaWN0aW9ucywKICAgICAgbW9kZWwgPSBtb2RlbCwKICAgICAgcGFyYW1ldGVycyA9IGNvZWYobW9kZWwpLAogICAgICBkYXRhID0gbW9kZWxfZGF0YQogICAgKQogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgewogICAgIyBUcnkgYWx0ZXJuYXRpdmUgZml0dGluZyBtZXRob2QgaWYgZmlyc3QgYXR0ZW1wdCBmYWlscwogICAgdHJ5Q2F0Y2goewogICAgICAjIFRyeSBzaW1wbGVyIDMtcGFyYW1ldGVyIGxvZ2lzdGljCiAgICAgIG1vZGVsIDwtIGRybShhZG9wdGlvbiB+IHllYXIsIAogICAgICAgICAgICAgICAgICAgZGF0YSA9IG1vZGVsX2RhdGEsCiAgICAgICAgICAgICAgICAgICBmY3QgPSBMLjMoKSkKICAgICAgCiAgICAgIGZ1dHVyZV95ZWFycyA8LSBzZXEobWluKG1vZGVsX2RhdGEkeWVhciksIGZvcmVjYXN0X3llYXIsIGJ5ID0gMSkKICAgICAgcHJlZGljdGlvbnMgPC0gdGliYmxlKAogICAgICAgIHllYXIgPSBmdXR1cmVfeWVhcnMsCiAgICAgICAgcHJlZGljdGVkX2Fkb3B0aW9uID0gcHJlZGljdChtb2RlbCwgZGF0YS5mcmFtZSh5ZWFyID0gZnV0dXJlX3llYXJzKSkKICAgICAgKQogICAgICAKICAgICAgbGlzdCgKICAgICAgICBwcmVkaWN0aW9ucyA9IHByZWRpY3Rpb25zLAogICAgICAgIG1vZGVsID0gbW9kZWwsCiAgICAgICAgcGFyYW1ldGVycyA9IGNvZWYobW9kZWwpLAogICAgICAgIGRhdGEgPSBtb2RlbF9kYXRhCiAgICAgICkKICAgIH0sIGVycm9yID0gZnVuY3Rpb24oZTIpIHsKICAgICAgY2F0KCJFcnJvciBmaXR0aW5nIG1vZGVsIGZvciIsIHRlY2hfY29sLCAiOiIsIGUyJG1lc3NhZ2UsICJcbiIpCiAgICAgIE5VTEwKICAgIH0pCiAgfSkKfQoKIyBGdW5jdGlvbiB0byBwbG90IGRpZmZ1c2lvbiBjdXJ2ZXMKcGxvdF9kaWZmdXNpb24gPC0gZnVuY3Rpb24ob3JpZ2luYWxfZGF0YSwgZm9yZWNhc3RfcmVzdWx0cywgdGVjaF9jb2wpIHsKICAjIENyZWF0ZSBiYXNlIHBsb3QKICBwIDwtIGdncGxvdCgpICsKICAgICMgSGlzdG9yaWNhbCBkYXRhCiAgICBnZW9tX3BvaW50KGRhdGEgPSBmb3JlY2FzdF9yZXN1bHRzJGRhdGEsCiAgICAgICAgICAgICAgIGFlcyh4ID0geWVhciwgeSA9IGFkb3B0aW9uKSwKICAgICAgICAgICAgICAgY29sb3IgPSAiYmx1ZSIsIHNpemUgPSAzLCBhbHBoYSA9IDAuNikgKwogICAgIyBGb3JlY2FzdCBsaW5lCiAgICBnZW9tX2xpbmUoZGF0YSA9IGZvcmVjYXN0X3Jlc3VsdHMkcHJlZGljdGlvbnMsCiAgICAgICAgICAgICAgYWVzKHggPSB5ZWFyLCB5ID0gcHJlZGljdGVkX2Fkb3B0aW9uKSwKICAgICAgICAgICAgICBjb2xvciA9ICJyZWQiLCBzaXplID0gMSkKICAKICAjIEFkZCBjb25maWRlbmNlIGludGVydmFscyBpZiBhdmFpbGFibGUKICBpZiAoImxvd2VyX2NpIiAlaW4lIG5hbWVzKGZvcmVjYXN0X3Jlc3VsdHMkcHJlZGljdGlvbnMpKSB7CiAgICBwIDwtIHAgKyBnZW9tX3JpYmJvbihkYXRhID0gZm9yZWNhc3RfcmVzdWx0cyRwcmVkaWN0aW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSB5ZWFyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHltaW4gPSBsb3dlcl9jaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHltYXggPSB1cHBlcl9jaSksCiAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gMC4yLCBmaWxsID0gInJlZCIpCiAgfQogIAogICMgQWRkIHN0eWxpbmcKICBwICsgdGhlbWVfbWluaW1hbCgpICsKICAgIGxhYnMoCiAgICAgIHRpdGxlID0gcGFzdGUoIlRlY2hub2xvZ3kgRGlmZnVzaW9uIEZvcmVjYXN0OiIsIAogICAgICAgICAgICAgICAgICAgZ3N1YigiX3BlcmNlbnQiLCAiIiwgdGVjaF9jb2wpKSwKICAgICAgc3VidGl0bGUgPSAiSGlzdG9yaWNhbCBkYXRhIGFuZCBsb2dpc3RpYyBncm93dGggcHJvamVjdGlvbiB0byAyMDUwIiwKICAgICAgeCA9ICJZZWFyIiwKICAgICAgeSA9ICJBZG9wdGlvbiBSYXRlICglKSIKICAgICkgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4ob3JpZ2luYWxfZGF0YSR5ZWFyKSwgMjA1MCwgYnkgPSA1KSkgKwogICAgeWxpbSgwLCAxMDApICsgICMgU2V0IHktYXhpcyBsaW1pdHMgdG8gMC0xMDAlCiAgICB0aGVtZSgKICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIKICAgICkKfQoKIyBEZWZpbmUgdGVjaG5vbG9naWVzCnRlY2hub2xvZ2llcyA8LSBjKCJzbWFydHBob25lX3BlcmNlbnQiLCAiaHlicmlkX3BlcmNlbnQiLCAic29sYXJfcGVyY2VudCIsIAogICAgICAgICAgICAgICAgICJpbnRlcm5ldF9wZXJjZW50IiwgInJlcGFpcnNfcGVyY2VudCIsICJza2lsbHNfcGVyY2VudCIsCiAgICAgICAgICAgICAgICAgImZ1ZWxfc3dpdGNoX3BlcmNlbnQiKQoKIyBDcmVhdGUgbGlzdCBmb3IgcmVzdWx0cwpmb3JlY2FzdHMgPC0gbGlzdCgpCgojIEZpdCBtb2RlbHMgYW5kIGNyZWF0ZSBwbG90cwpmb3IodGVjaCBpbiB0ZWNobm9sb2dpZXMpIHsKICBjYXQoIlxuUHJvY2Vzc2luZyIsIHRlY2gsICIuLi5cbiIpCiAgZm9yZWNhc3RzW1t0ZWNoXV0gPC0gZm9yZWNhc3RfZGlmZnVzaW9uKHVzX3Byb3BzLCB0ZWNoKQogIAogIGlmKCFpcy5udWxsKGZvcmVjYXN0c1tbdGVjaF1dKSkgewogICAgcGxvdCA8LSBwbG90X2RpZmZ1c2lvbih1c19wcm9wcywgZm9yZWNhc3RzW1t0ZWNoXV0sIHRlY2gpCiAgICBwcmludChwbG90KQogICAgCiAgICAjIFByaW50IHNvbWUgbW9kZWwgZGlhZ25vc3RpY3MKICAgIGNhdCgiRml0dGVkIHN1Y2Nlc3NmdWxseS4gRmluYWwgYWRvcHRpb24gcmF0ZSBwcmVkaWN0aW9uIGZvciAyMDUwOiIsIAogICAgICAgIHJvdW5kKHRhaWwoZm9yZWNhc3RzW1t0ZWNoXV0kcHJlZGljdGlvbnMkcHJlZGljdGVkX2Fkb3B0aW9uLCAxKSwgMSksIAogICAgICAgICIlXG4iKQogIH0gZWxzZSB7CiAgICBjYXQoIkZhaWxlZCB0byBjcmVhdGUgZm9yZWNhc3QgZm9yIiwgdGVjaCwgIlxuIikKICB9Cn0KCiMgR2V0IGZvcmVjYXN0IG1ldHJpY3MKZm9yZWNhc3RfbWV0cmljcyA8LSBtYXBfZGYobmFtZXMoZm9yZWNhc3RzKSwgZnVuY3Rpb24odGVjaCkgewogIGlmKCFpcy5udWxsKGZvcmVjYXN0c1tbdGVjaF1dKSkgewogICAgcHJlZCA8LSBmb3JlY2FzdHNbW3RlY2hdXSRwcmVkaWN0aW9ucwogICAgCiAgICB0aWJibGUoCiAgICAgIHRlY2hub2xvZ3kgPSBnc3ViKCJfcGVyY2VudCIsICIiLCB0ZWNoKSwKICAgICAgYWRvcHRpb25fMjAzMCA9IHJvdW5kKHByZWQkcHJlZGljdGVkX2Fkb3B0aW9uW3ByZWQkeWVhciA9PSAyMDMwXSwgMSksCiAgICAgIGFkb3B0aW9uXzIwNDAgPSByb3VuZChwcmVkJHByZWRpY3RlZF9hZG9wdGlvbltwcmVkJHllYXIgPT0gMjA0MF0sIDEpLAogICAgICBhZG9wdGlvbl8yMDUwID0gcm91bmQocHJlZCRwcmVkaWN0ZWRfYWRvcHRpb25bcHJlZCR5ZWFyID09IDIwNTBdLCAxKQogICAgKQogIH0KfSkKCiMgUHJpbnQgc3VtbWFyeQpjYXQoIlxuRm9yZWNhc3QgQWRvcHRpb24gUmF0ZXM6XG4iKQpwcmludChmb3JlY2FzdF9tZXRyaWNzICU+JSBhcnJhbmdlKGRlc2MoYWRvcHRpb25fMjA1MCkpKQpgYGAKCmBgYHtyIFVTIGRpZmZ1c2lvbiBieSBkZWNpbGUsIGVjaG89VFJVRX0KIyBMb2FkIHJlcXVpcmVkIHBhY2thZ2VzCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KG5sczIpCgojIEZ1bmN0aW9uIHRvIGZpdCBsb2dpc3RpYyBncm93dGggbW9kZWwgZm9yIGEgc3BlY2lmaWMgZGVjaWxlCmZvcmVjYXN0X2xvZ2lzdGljX2dyb3d0aCA8LSBmdW5jdGlvbihkYXRhLCB0ZWNoX2NvbCwgZGVjaWxlX3ZhbCwgZm9yZWNhc3RfeWVhciA9IDIwNTApIHsKICAjIENyZWF0ZSBtb2RlbCBkYXRhIGZvciBzcGVjaWZpYyBkZWNpbGUKICBtb2RlbF9kYXRhIDwtIHRpYmJsZSgKICAgIHllYXIgPSBkYXRhJHllYXJbZGF0YSRkZWNpbGUgPT0gZGVjaWxlX3ZhbF0sCiAgICBhZG9wdGlvbiA9IGRhdGFbW3RlY2hfY29sXV1bZGF0YSRkZWNpbGUgPT0gZGVjaWxlX3ZhbF0KICApICU+JQogICAgYXJyYW5nZSh5ZWFyKSAlPiUKICAgIGZpbHRlcighaXMubmEoYWRvcHRpb24pKQogIAogICMgTm9ybWFsaXplIHllYXJzIHRvIHN0YXJ0IGZyb20gMCBmb3IgYmV0dGVyIG1vZGVsIGZpdHRpbmcKICBtb2RlbF9kYXRhJHQgPC0gbW9kZWxfZGF0YSR5ZWFyIC0gbWluKG1vZGVsX2RhdGEkeWVhcikKICAKICAjIEdldCBpbml0aWFsIHBhcmFtZXRlciBlc3RpbWF0ZXMKICBLX2d1ZXNzIDwtIG1heCgxMDAsIG1heChtb2RlbF9kYXRhJGFkb3B0aW9uKSAqIDEuMikgICMgQ2FycnlpbmcgY2FwYWNpdHkKICByX2d1ZXNzIDwtIDAuNSAgIyBHcm93dGggcmF0ZQogIE4wX2d1ZXNzIDwtIG1vZGVsX2RhdGEkYWRvcHRpb25bMV0gICMgSW5pdGlhbCBhZG9wdGlvbgogIAogIHRyeUNhdGNoKHsKICAgICMgRml0IGxvZ2lzdGljIGdyb3d0aCBtb2RlbCB1c2luZyBubHMKICAgICMgRm9ybXVsYTogTih0KSA9IEsgLyAoMSArICgoSyAtIE4wKS9OMCkgKiBleHAoLXIqdCkpCiAgICBtb2RlbCA8LSBubHMoYWRvcHRpb24gfiBLIC8gKDEgKyAoKEsgLSBOMCkvTjApICogZXhwKC1yICogdCkpLAogICAgICAgICAgICAgICAgIGRhdGEgPSBtb2RlbF9kYXRhLAogICAgICAgICAgICAgICAgIHN0YXJ0ID0gbGlzdChLID0gS19ndWVzcywgciA9IHJfZ3Vlc3MsIE4wID0gTjBfZ3Vlc3MpLAogICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBubHMuY29udHJvbChtYXhpdGVyID0gMTAwMCkpCiAgICAKICAgICMgR2VuZXJhdGUgZnV0dXJlIHllYXJzIGZvciBwcmVkaWN0aW9uCiAgICBmdXR1cmVfeWVhcnMgPC0gc2VxKG1pbihtb2RlbF9kYXRhJHllYXIpLCBmb3JlY2FzdF95ZWFyLCBieSA9IDEpCiAgICBmdXR1cmVfdCA8LSBmdXR1cmVfeWVhcnMgLSBtaW4obW9kZWxfZGF0YSR5ZWFyKQogICAgCiAgICAjIEV4dHJhY3QgcGFyYW1ldGVycwogICAgcGFyYW1zIDwtIGNvZWYobW9kZWwpCiAgICBLIDwtIHBhcmFtc1siSyJdCiAgICByIDwtIHBhcmFtc1siciJdCiAgICBOMCA8LSBwYXJhbXNbIk4wIl0KICAgIAogICAgIyBHZW5lcmF0ZSBwcmVkaWN0aW9ucwogICAgcHJlZGljdGlvbnMgPC0gdGliYmxlKAogICAgICB5ZWFyID0gZnV0dXJlX3llYXJzLAogICAgICB0ID0gZnV0dXJlX3QsCiAgICAgIHByZWRpY3RlZF9hZG9wdGlvbiA9IEsgLyAoMSArICgoSyAtIE4wKS9OMCkgKiBleHAoLXIgKiB0KSksCiAgICAgIGRlY2lsZSA9IGRlY2lsZV92YWwKICAgICkKICAgIAogICAgbGlzdCgKICAgICAgcHJlZGljdGlvbnMgPSBwcmVkaWN0aW9ucywKICAgICAgbW9kZWwgPSBtb2RlbCwKICAgICAgcGFyYW1ldGVycyA9IHBhcmFtcywKICAgICAgZGF0YSA9IG1vZGVsX2RhdGEsCiAgICAgIEsgPSBLLAogICAgICByID0gciwKICAgICAgTjAgPSBOMAogICAgKQogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgewogICAgY2F0KCJFcnJvciBmaXR0aW5nIG1vZGVsIGZvciBkZWNpbGUiLCBkZWNpbGVfdmFsLCAiOiIsIGUkbWVzc2FnZSwgIlxuIikKICAgIE5VTEwKICB9KQp9CgojIEZ1bmN0aW9uIHRvIHBsb3QgZ3Jvd3RoIGN1cnZlcyBieSBkZWNpbGUKcGxvdF9sb2dpc3RpY19ncm93dGggPC0gZnVuY3Rpb24oZm9yZWNhc3RzX2xpc3QsIHRlY2hfY29sKSB7CiAgIyBDb21iaW5lIGFsbCBwcmVkaWN0aW9ucwogIGFsbF9wcmVkaWN0aW9ucyA8LSBiaW5kX3Jvd3MoCiAgICBsYXBwbHkoZm9yZWNhc3RzX2xpc3QsIGZ1bmN0aW9uKHgpIHgkcHJlZGljdGlvbnMpCiAgKQogIAogICMgQ29tYmluZSBhbGwgaGlzdG9yaWNhbCBkYXRhCiAgYWxsX2RhdGEgPC0gYmluZF9yb3dzKAogICAgbGFwcGx5KGZvcmVjYXN0c19saXN0LCBmdW5jdGlvbih4KSB7CiAgICAgIHgkZGF0YSAlPiUgbXV0YXRlKGRlY2lsZSA9IHgkcHJlZGljdGlvbnMkZGVjaWxlWzFdKQogICAgfSkKICApCiAgCiAgIyBDcmVhdGUgcGxvdAogIGdncGxvdCgpICsKICAgICMgSGlzdG9yaWNhbCBkYXRhIHBvaW50cwogICAgZ2VvbV9wb2ludChkYXRhID0gYWxsX2RhdGEsCiAgICAgICAgICAgICAgIGFlcyh4ID0geWVhciwgeSA9IGFkb3B0aW9uLCBjb2xvciA9IGZhY3RvcihkZWNpbGUpKSwKICAgICAgICAgICAgICAgYWxwaGEgPSAwLjYsIHNpemUgPSAyKSArCiAgICAjIEZvcmVjYXN0IGxpbmVzCiAgICBnZW9tX2xpbmUoZGF0YSA9IGFsbF9wcmVkaWN0aW9ucywKICAgICAgICAgICAgICBhZXMoeCA9IHllYXIsIHkgPSBwcmVkaWN0ZWRfYWRvcHRpb24sIGNvbG9yID0gZmFjdG9yKGRlY2lsZSkpKSArCiAgICBzY2FsZV9jb2xvcl92aXJpZGlzX2QobmFtZSA9ICJJbmNvbWUgRGVjaWxlIikgKwogICAgdGhlbWVfbWluaW1hbCgpICsKICAgIGxhYnMoCiAgICAgIHRpdGxlID0gcGFzdGUoIkxvZ2lzdGljIEdyb3d0aCBGb3JlY2FzdCBieSBJbmNvbWUgRGVjaWxlOiIsIAogICAgICAgICAgICAgICAgICAgZ3N1YigiX3BlcmNlbnQiLCAiIiwgdGVjaF9jb2wpKSwKICAgICAgc3VidGl0bGUgPSAiSGlzdG9yaWNhbCBkYXRhIGFuZCBsb2dpc3RpYyBncm93dGggcHJvamVjdGlvbnMgdG8gMjA1MCIsCiAgICAgIHggPSAiWWVhciIsCiAgICAgIHkgPSAiQWRvcHRpb24gUmF0ZSAoJSkiCiAgICApICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMjAxMCwgMjA1MCwgYnkgPSA1KSkgKwogICAgeWxpbSgwLCAxMDApICsKICAgIHRoZW1lKAogICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiCiAgICApCn0KCiMgRGVmaW5lIHRlY2hub2xvZ2llcwp0ZWNobm9sb2dpZXMgPC0gYygic21hcnRwaG9uZV9wZXJjZW50IiwgImh5YnJpZF9wZXJjZW50IiwgInNvbGFyX3BlcmNlbnQiLCAKICAgICAgICAgICAgICAgICAiaW50ZXJuZXRfcGVyY2VudCIsICJyZXBhaXJzX3BlcmNlbnQiLCAic2tpbGxzX3BlcmNlbnQiLAogICAgICAgICAgICAgICAgICJmdWVsX3N3aXRjaF9wZXJjZW50IikKCiMgQ3JlYXRlIG5lc3RlZCBsaXN0IGZvciByZXN1bHRzCmZvcmVjYXN0c19ieV9kZWNpbGUgPC0gbGlzdCgpCgojIEZpdCBtb2RlbHMgZm9yIGVhY2ggdGVjaG5vbG9neSBhbmQgZGVjaWxlCmZvcih0ZWNoIGluIHRlY2hub2xvZ2llcykgewogIGNhdCgiXG5Qcm9jZXNzaW5nIiwgdGVjaCwgIlxuIikKICAKICAjIFN0b3JlIGZvcmVjYXN0cyBmb3IgZWFjaCBkZWNpbGUKICBkZWNpbGVfZm9yZWNhc3RzIDwtIGxpc3QoKQogIAogIGZvcihkIGluIDE6MTApIHsKICAgIGNhdCgiICBEZWNpbGUiLCBkLCAiXG4iKQogICAgZGVjaWxlX2ZvcmVjYXN0c1tbZF1dIDwtIGZvcmVjYXN0X2xvZ2lzdGljX2dyb3d0aCh1c19wcm9wcywgdGVjaCwgZCkKICB9CiAgCiAgIyBTdG9yZSBhbmQgcGxvdCBpZiB3ZSBoYXZlIHN1Y2Nlc3NmdWwgZml0cwogIGlmKGFueSghc2FwcGx5KGRlY2lsZV9mb3JlY2FzdHMsIGlzLm51bGwpKSkgewogICAgZm9yZWNhc3RzX2J5X2RlY2lsZVtbdGVjaF1dIDwtIGRlY2lsZV9mb3JlY2FzdHMKICAgIAogICAgIyBDcmVhdGUgYW5kIHByaW50IHBsb3QKICAgIHBsb3QgPC0gcGxvdF9sb2dpc3RpY19ncm93dGgoZGVjaWxlX2ZvcmVjYXN0c1shc2FwcGx5KGRlY2lsZV9mb3JlY2FzdHMsIGlzLm51bGwpXSwgdGVjaCkKICAgIHByaW50KHBsb3QpCiAgICAKICAgICMgUHJpbnQgbW9kZWwgcGFyYW1ldGVycyBhbmQgcHJlZGljdGlvbnMKICAgIGNhdCgiXG5Mb2dpc3RpYyBHcm93dGggUGFyYW1ldGVycyBmb3IiLCBnc3ViKCJfcGVyY2VudCIsICIiLCB0ZWNoKSwgIjpcbiIpCiAgICBwYXJhbWV0ZXJfc3VtbWFyeSA8LSBiaW5kX3Jvd3MobGFwcGx5KGRlY2lsZV9mb3JlY2FzdHNbIXNhcHBseShkZWNpbGVfZm9yZWNhc3RzLCBpcy5udWxsKV0sIGZ1bmN0aW9uKHgpIHsKICAgICAgdGliYmxlKAogICAgICAgIGRlY2lsZSA9IHgkcHJlZGljdGlvbnMkZGVjaWxlWzFdLAogICAgICAgIGNhcnJ5aW5nX2NhcGFjaXR5ID0gcm91bmQoeCRLLCAxKSwKICAgICAgICBncm93dGhfcmF0ZSA9IHJvdW5kKHgkciwgMyksCiAgICAgICAgaW5pdGlhbF9hZG9wdGlvbiA9IHJvdW5kKHgkTjAsIDEpLAogICAgICAgIGFkb3B0aW9uXzIwMzAgPSByb3VuZCh4JHByZWRpY3Rpb25zJHByZWRpY3RlZF9hZG9wdGlvblt4JHByZWRpY3Rpb25zJHllYXIgPT0gMjAzMF0sIDEpLAogICAgICAgIGFkb3B0aW9uXzIwNDAgPSByb3VuZCh4JHByZWRpY3Rpb25zJHByZWRpY3RlZF9hZG9wdGlvblt4JHByZWRpY3Rpb25zJHllYXIgPT0gMjA0MF0sIDEpLAogICAgICAgIGFkb3B0aW9uXzIwNTAgPSByb3VuZCh4JHByZWRpY3Rpb25zJHByZWRpY3RlZF9hZG9wdGlvblt4JHByZWRpY3Rpb25zJHllYXIgPT0gMjA1MF0sIDEpCiAgICAgICkKICAgIH0pKQogICAgcHJpbnQocGFyYW1ldGVyX3N1bW1hcnkgJT4lIGFycmFuZ2UoZGVjaWxlKSkKICB9Cn0KCmBgYAoKYGBge3IgZW5lcmd5IGRhdGEsIGVjaG89VFJVRX0KIyBDcmVhdGUgaGlzdG9yaWNhbCBwcmljZSBkYXRhc2V0IChFSUEgQXZlcmFnZSBSZXRhaWwgRWxlY3RyaWNpdHkgYW5kIEdhcyAyMDA1IC0gMjAyMikKaGlzdG9yaWNhbF9wcmljZXMgPC0gdGliYmxlKAogIHllYXIgPSAyMDA1OjIwMjIsCiAgZWxlY19wcmljZSA9IGMoOS40NSwgMTAuNDAsIDEwLjY1LCAxMS4yNiwgMTEuNTEsIDExLjU0LCAxMS43MiwgMTEuODgsIDEyLjEzLAogICAgICAgICAgICAgICAgIDEyLjUyLCAxMi42NSwgMTIuNTUsIDEyLjg5LCAxMi44NywgMTMuMDEsIDEzLjE1LCAxMy43MiwgMTQuNzcpLCAgIyBjZW50cyBwZXIga1doCiAgZ2FzX3ByaWNlID0gYygxMy44MywgMTMuNzMsIDEzLjA4LCAxMy44OSwgMTIuMTQsIDExLjM5LCAxMS4wMywgMTAuNzEsIDEwLjMyLAogICAgICAgICAgICAgICAgMTAuOTcsIDEwLjM4LCAxMC4wNSwgMTAuOTEsIDEwLjUwLCAxMC40NCwgMTAuNzgsIDExLjQ3LCAxNS45NSkgICAjIGRvbGxhcnMgcGVyIHRob3VzYW5kIGN1YmljIGZlZXQKKQoKIyBNZXJnZSB3aXRoIFVTIGRhdGFzZXQKVVMgPC0gVVMgJT4lCiAgbGVmdF9qb2luKGhpc3RvcmljYWxfcHJpY2VzLCBieSA9ICJ5ZWFyIikKCiMgUHJpbnQgc3VtbWFyeSBvZiB0aGUgbmV3IGNvbHVtbnMKY2F0KCJTdW1tYXJ5IG9mIGFkZGVkIGVuZXJneSBwcmljZSBjb2x1bW5zOlxuIikKc3VtbWFyeShVU1tjKCJlbGVjX3ByaWNlIiwgImdhc19wcmljZSIpXSkKCiMgQ3JlYXRlIHF1aWNrIHZpc3VhbGl6YXRpb24gb2YgcHJpY2UgdHJlbmRzCmdncGxvdChoaXN0b3JpY2FsX3ByaWNlcywgYWVzKHggPSB5ZWFyKSkgKwogIGdlb21fbGluZShhZXMoeSA9IGVsZWNfcHJpY2UsIGNvbG9yID0gIkVsZWN0cmljaXR5IiksIHNpemUgPSAxKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gZ2FzX3ByaWNlLCBjb2xvciA9ICJOYXR1cmFsIEdhcyIpLCBzaXplID0gMSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicygKICAgIHRpdGxlID0gIkhpc3RvcmljYWwgRW5lcmd5IFByaWNlcyAoMjAwNS0yMDIyKSIsCiAgICB5ID0gIlByaWNlIiwKICAgIGNvbG9yID0gIkVuZXJneSBUeXBlIgogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJFbGVjdHJpY2l0eSIgPSAiYmx1ZSIsICJOYXR1cmFsIEdhcyIgPSAicmVkIikpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IG1heChoaXN0b3JpY2FsX3ByaWNlcyR5ZWFyKSwgeSA9IG1heChoaXN0b3JpY2FsX3ByaWNlcyRlbGVjX3ByaWNlKSwKICAgICAgICAgICBsYWJlbCA9ICJjZW50cyBwZXIga1doIiwgaGp1c3QgPSAxLCB2anVzdCA9IC0wLjUpICsKICBhbm5vdGF0ZSgidGV4dCIsIHggPSBtYXgoaGlzdG9yaWNhbF9wcmljZXMkeWVhciksIHkgPSBtYXgoaGlzdG9yaWNhbF9wcmljZXMkZ2FzX3ByaWNlKSwKICAgICAgICAgICBsYWJlbCA9ICJkb2xsYXJzIHBlciB0aG91c2FuZCBjdWJpYyBmZWV0IiwgaGp1c3QgPSAxLCB2anVzdCA9IC0wLjUpCmBgYAoKYGBge3IgVVMgY29uc3VtcHRpb24sIGVjaG89VFJVRX0KIyBDYWxjdWxhdGUgZW5lcmd5IGNvbnN1bXB0aW9uClVTIDwtIFVTICU+JQogIG11dGF0ZSgKICAgICMgQ29udmVydCBlbGVjdHJpY2l0eSBleHBlbmRpdHVyZSB0byBrV2gKICAgICMgZWxlY19wcmljZSBpcyBpbiBjZW50cyBwZXIga1doLCBzbyBtdWx0aXBseSBieSAxMDAgdG8gY29udmVydCB0byBkb2xsYXJzCiAgICBlbGVjX2NvbnN1bXB0aW9uX2t3aCA9IChlbGVjX2FfZXhwIC8gKGVsZWNfcHJpY2UvMTAwKSksCiAgICAKICAgICMgQ29udmVydCBnYXMgZXhwZW5kaXR1cmUgdG8gdGhvdXNhbmQgY3ViaWMgZmVldAogICAgZ2FzX2NvbnN1bXB0aW9uX3RjZiA9IGdhc19hX2V4cCAvIGdhc19wcmljZSwKICAgIAogICAgIyBDYWxjdWxhdGUgY29uc3VtcHRpb24gcGVyIHJvb20gKHRvIGFjY291bnQgZm9yIGhvdXNlIHNpemUpCiAgICBlbGVjX2NvbnN1bXB0aW9uX3Blcl9yb29tID0gZWxlY19jb25zdW1wdGlvbl9rd2ggLyBoaF9yb29tcywKICAgIGdhc19jb25zdW1wdGlvbl9wZXJfcm9vbSA9IGdhc19jb25zdW1wdGlvbl90Y2YgLyBoaF9yb29tcwogICkKCiMgQ3JlYXRlIHN1bW1hcnkgc3RhdGlzdGljcwpjb25zdW1wdGlvbl9zdW1tYXJ5IDwtIFVTICU+JQogIGdyb3VwX2J5KHllYXIpICU+JQogIHN1bW1hcmlzZSgKICAgIGF2Z19lbGVjX2t3aCA9IG1lYW4oZWxlY19jb25zdW1wdGlvbl9rd2gsIG5hLnJtID0gVFJVRSksCiAgICBtZWRpYW5fZWxlY19rd2ggPSBtZWRpYW4oZWxlY19jb25zdW1wdGlvbl9rd2gsIG5hLnJtID0gVFJVRSksCiAgICBhdmdfZ2FzX3RjZiA9IG1lYW4oZ2FzX2NvbnN1bXB0aW9uX3RjZiwgbmEucm0gPSBUUlVFKSwKICAgIG1lZGlhbl9nYXNfdGNmID0gbWVkaWFuKGdhc19jb25zdW1wdGlvbl90Y2YsIG5hLnJtID0gVFJVRSksCiAgICBhdmdfZWxlY19wZXJfcm9vbSA9IG1lYW4oZWxlY19jb25zdW1wdGlvbl9wZXJfcm9vbSwgbmEucm0gPSBUUlVFKSwKICAgIGF2Z19nYXNfcGVyX3Jvb20gPSBtZWFuKGdhc19jb25zdW1wdGlvbl9wZXJfcm9vbSwgbmEucm0gPSBUUlVFKQogICkKCiMgUHJpbnQgc3VtbWFyeSBzdGF0aXN0aWNzCnByaW50KCJBdmVyYWdlIEFubnVhbCBFbmVyZ3kgQ29uc3VtcHRpb246IikKcHJpbnQoY29uc3VtcHRpb25fc3VtbWFyeSkKCiMgQ3JlYXRlIHZpc3VhbGl6YXRpb24gb2YgY29uc3VtcHRpb24gdHJlbmRzCmdncGxvdChjb25zdW1wdGlvbl9zdW1tYXJ5LCBhZXMoeCA9IHllYXIpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gYXZnX2VsZWNfa3doLCBjb2xvciA9ICJFbGVjdHJpY2l0eSAoa1doKSIpLCBzaXplID0gMSkgKwogIGdlb21fbGluZShhZXMoeSA9IGF2Z19nYXNfdGNmICogMTAwMCwgY29sb3IgPSAiR2FzIChjZikiKSwgc2l6ZSA9IDEpICsgICMgTXVsdGlwbHkgYnkgMTAwMCB0byBjb252ZXJ0IHRvIGN1YmljIGZlZXQKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJBdmVyYWdlIEhvdXNlaG9sZCBFbmVyZ3kgQ29uc3VtcHRpb24gT3ZlciBUaW1lIiwKICAgIHkgPSAiQ29uc3VtcHRpb24iLAogICAgY29sb3IgPSAiRW5lcmd5IFR5cGUiCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIkVsZWN0cmljaXR5IChrV2gpIiA9ICJibHVlIiwgIkdhcyAoY2YpIiA9ICJyZWQiKSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQoKIyBDcmVhdGUgYm94cGxvdCBvZiBjb25zdW1wdGlvbiBieSBob3VzZSBzaXplCmdncGxvdChVUywgYWVzKHggPSBmYWN0b3IoaGhfcm9vbXMpLCB5ID0gZWxlY19jb25zdW1wdGlvbl9rd2gpKSArCiAgZ2VvbV9ib3hwbG90KGFscGhhID0gMC41KSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKAogICAgdGl0bGUgPSAiRWxlY3RyaWNpdHkgQ29uc3VtcHRpb24gYnkgTnVtYmVyIG9mIFJvb21zIiwKICAgIHggPSAiTnVtYmVyIG9mIFJvb21zIiwKICAgIHkgPSAiQW5udWFsIEVsZWN0cmljaXR5IENvbnN1bXB0aW9uIChrV2gpIgogICkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCiMgQmFzaWMgc2FuaXR5IGNoZWNrcyAocHJpbnQgcmFuZ2VzIHRvIGNoZWNrIGZvciB1bnJlYXNvbmFibGUgdmFsdWVzKQpjYXQoIlxuQ29uc3VtcHRpb24gUmFuZ2VzIChyZW1vdmluZyBvdXRsaWVycyk6XG4iKQpjb25zdW1wdGlvbl9yYW5nZXMgPC0gVVMgJT4lCiAgc3VtbWFyaXNlKAogICAgZWxlY19rd2hfbWluID0gcXVhbnRpbGUoZWxlY19jb25zdW1wdGlvbl9rd2gsIDAuMDUsIG5hLnJtID0gVFJVRSksCiAgICBlbGVjX2t3aF9tYXggPSBxdWFudGlsZShlbGVjX2NvbnN1bXB0aW9uX2t3aCwgMC45NSwgbmEucm0gPSBUUlVFKSwKICAgIGdhc190Y2ZfbWluID0gcXVhbnRpbGUoZ2FzX2NvbnN1bXB0aW9uX3RjZiwgMC4wNSwgbmEucm0gPSBUUlVFKSwKICAgIGdhc190Y2ZfbWF4ID0gcXVhbnRpbGUoZ2FzX2NvbnN1bXB0aW9uX3RjZiwgMC45NSwgbmEucm0gPSBUUlVFKQogICkKcHJpbnQoY29uc3VtcHRpb25fcmFuZ2VzKQoKYGBgCgpgYGB7ciBVUyB1cHRha2UgY29uc3VtcHRpb24sIGVjaG89VFJVRX0KCiMgRmlyc3QsIGdlbmVyYXRlIGZvcmVjYXN0cyBmb3IgZWFjaCB0ZWNobm9sb2d5IGFuZCBkZWNpbGUKZm9yZWNhc3RfbG9naXN0aWNfZ3Jvd3RoIDwtIGZ1bmN0aW9uKGRhdGEsIHRlY2hfY29sLCBkZWNpbGVfdmFsLCBmb3JlY2FzdF95ZWFyID0gMjA1MCkgewogICMgQ3JlYXRlIG1vZGVsIGRhdGEgZm9yIHNwZWNpZmljIGRlY2lsZQogIG1vZGVsX2RhdGEgPC0gdGliYmxlKAogICAgeWVhciA9IGRhdGEkeWVhcltkYXRhJGRlY2lsZSA9PSBkZWNpbGVfdmFsXSwKICAgIGFkb3B0aW9uID0gZGF0YVtbdGVjaF9jb2xdXVtkYXRhJGRlY2lsZSA9PSBkZWNpbGVfdmFsXQogICkgJT4lCiAgICBhcnJhbmdlKHllYXIpICU+JQogICAgZmlsdGVyKCFpcy5uYShhZG9wdGlvbikpCiAgCiAgIyBOb3JtYWxpemUgeWVhcnMgdG8gc3RhcnQgZnJvbSAwIGZvciBiZXR0ZXIgbW9kZWwgZml0dGluZwogIG1vZGVsX2RhdGEkdCA8LSBtb2RlbF9kYXRhJHllYXIgLSBtaW4obW9kZWxfZGF0YSR5ZWFyKQogIAogIHRyeUNhdGNoKHsKICAgICMgR2V0IGluaXRpYWwgcGFyYW1ldGVyIGVzdGltYXRlcwogICAgS19ndWVzcyA8LSBtYXgoMTAwLCBtYXgobW9kZWxfZGF0YSRhZG9wdGlvbikgKiAxLjIpICAjIENhcnJ5aW5nIGNhcGFjaXR5CiAgICByX2d1ZXNzIDwtIDAuNSAgIyBHcm93dGggcmF0ZQogICAgTjBfZ3Vlc3MgPC0gbW9kZWxfZGF0YSRhZG9wdGlvblsxXSAgIyBJbml0aWFsIGFkb3B0aW9uCiAgICAKICAgICMgRml0IGxvZ2lzdGljIGdyb3d0aCBtb2RlbCB1c2luZyBubHMKICAgIG1vZGVsIDwtIG5scyhhZG9wdGlvbiB+IEsgLyAoMSArICgoSyAtIE4wKS9OMCkgKiBleHAoLXIgKiB0KSksCiAgICAgICAgICAgICAgICAgZGF0YSA9IG1vZGVsX2RhdGEsCiAgICAgICAgICAgICAgICAgc3RhcnQgPSBsaXN0KEsgPSBLX2d1ZXNzLCByID0gcl9ndWVzcywgTjAgPSBOMF9ndWVzcyksCiAgICAgICAgICAgICAgICAgY29udHJvbCA9IG5scy5jb250cm9sKG1heGl0ZXIgPSAxMDAwKSkKICAgIAogICAgIyBHZW5lcmF0ZSBmdXR1cmUgeWVhcnMgZm9yIHByZWRpY3Rpb24KICAgIGZ1dHVyZV95ZWFycyA8LSBzZXEobWluKG1vZGVsX2RhdGEkeWVhciksIGZvcmVjYXN0X3llYXIsIGJ5ID0gMSkKICAgIGZ1dHVyZV90IDwtIGZ1dHVyZV95ZWFycyAtIG1pbihtb2RlbF9kYXRhJHllYXIpCiAgICAKICAgICMgRXh0cmFjdCBwYXJhbWV0ZXJzCiAgICBwYXJhbXMgPC0gY29lZihtb2RlbCkKICAgIEsgPC0gcGFyYW1zWyJLIl0KICAgIHIgPC0gcGFyYW1zWyJyIl0KICAgIE4wIDwtIHBhcmFtc1siTjAiXQogICAgCiAgICAjIEdlbmVyYXRlIHByZWRpY3Rpb25zCiAgICBwcmVkaWN0aW9ucyA8LSB0aWJibGUoCiAgICAgIHllYXIgPSBmdXR1cmVfeWVhcnMsCiAgICAgIHQgPSBmdXR1cmVfdCwKICAgICAgcHJlZGljdGVkX2Fkb3B0aW9uID0gSyAvICgxICsgKChLIC0gTjApL04wKSAqIGV4cCgtciAqIHQpKSwKICAgICAgZGVjaWxlID0gZGVjaWxlX3ZhbAogICAgKQogICAgCiAgICByZXR1cm4obGlzdCgKICAgICAgcHJlZGljdGlvbnMgPSBwcmVkaWN0aW9ucywKICAgICAgbW9kZWwgPSBtb2RlbCwKICAgICAgcGFyYW1ldGVycyA9IHBhcmFtcywKICAgICAgZGF0YSA9IG1vZGVsX2RhdGEsCiAgICAgIEsgPSBLLAogICAgICByID0gciwKICAgICAgTjAgPSBOMAogICAgKSkKICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgIGNhdCgiRXJyb3IgZml0dGluZyBtb2RlbCBmb3IgZGVjaWxlIiwgZGVjaWxlX3ZhbCwgIjoiLCBlJG1lc3NhZ2UsICJcbiIpCiAgICByZXR1cm4oTlVMTCkKICB9KQp9CgojIEdlbmVyYXRlIGZvcmVjYXN0cwp0ZWNobm9sb2dpZXMgPC0gYygiaHlicmlkX3Byb3AiLCAic29sYXJfcHJvcCIsICJmdWVsX3N3aXRjaF9wcm9wIikKZm9yZWNhc3RzX2J5X2RlY2lsZSA8LSBsaXN0KCkKCmZvcih0ZWNoIGluIHRlY2hub2xvZ2llcykgewogIGNhdCgiXG5HZW5lcmF0aW5nIGZvcmVjYXN0cyBmb3IiLCB0ZWNoLCAiXG4iKQogIHRlY2hfZm9yZWNhc3RzIDwtIGxpc3QoKQogIAogIGZvcihkIGluIDE6MTApIHsKICAgIGNhdCgiICBQcm9jZXNzaW5nIGRlY2lsZSIsIGQsICJcbiIpCiAgICB0ZWNoX2ZvcmVjYXN0c1tbZF1dIDwtIGZvcmVjYXN0X2xvZ2lzdGljX2dyb3d0aCh1c19wcm9wcywgdGVjaCwgZCkKICB9CiAgCiAgZm9yZWNhc3RzX2J5X2RlY2lsZVtbdGVjaF1dIDwtIHRlY2hfZm9yZWNhc3RzCn0KCiMgTm93IGNhbGN1bGF0ZSBlbmVyZ3kgaW1wYWN0cwojIEdldCBjdXJyZW50IGFkb3B0aW9uIHJhdGVzCm1heF95ZWFyIDwtIG1heCh1c19wcm9wcyR5ZWFyKQpjdXJyZW50X3JhdGVzIDwtIGRhdGEuZnJhbWUoCiAgZGVjaWxlID0gdXNfcHJvcHMkZGVjaWxlW3VzX3Byb3BzJHllYXIgPT0gbWF4X3llYXJdLAogIGN1cnJlbnRfaHlicmlkID0gdXNfcHJvcHMkaHlicmlkX3Byb3BbdXNfcHJvcHMkeWVhciA9PSBtYXhfeWVhcl0sCiAgY3VycmVudF9zb2xhciA9IHVzX3Byb3BzJHNvbGFyX3Byb3BbdXNfcHJvcHMkeWVhciA9PSBtYXhfeWVhcl0sCiAgY3VycmVudF9mdWVsX3N3aXRjaCA9IHVzX3Byb3BzJGZ1ZWxfc3dpdGNoX3Byb3BbdXNfcHJvcHMkeWVhciA9PSBtYXhfeWVhcl0KKQoKIyBDYWxjdWxhdGUgYmFzZWxpbmUgY29uc3VtcHRpb24KYmFzZWxpbmVfY29uc3VtcHRpb24gPC0gVVMgJT4lCiAgZ3JvdXBfYnkoZGVjaWxlKSAlPiUKICBzdW1tYXJpc2UoCiAgICBhdmdfZW5lcmd5X3dpdGhfaHlicmlkID0gbWVhbihlbGVjX2NvbnN1bXB0aW9uX2t3aFtoeWJyaWQgPT0gMV0sIG5hLnJtID0gVFJVRSksCiAgICBhdmdfZW5lcmd5X25vX2h5YnJpZCA9IG1lYW4oZWxlY19jb25zdW1wdGlvbl9rd2hbaHlicmlkID09IDBdLCBuYS5ybSA9IFRSVUUpLAogICAgaHlicmlkX2ltcGFjdCA9IGF2Z19lbmVyZ3lfd2l0aF9oeWJyaWQgLSBhdmdfZW5lcmd5X25vX2h5YnJpZCwKICAgIAogICAgYXZnX2VuZXJneV93aXRoX3NvbGFyID0gbWVhbihlbGVjX2NvbnN1bXB0aW9uX2t3aFtoZWF0X21ldGhvZCA9PSA2XSwgbmEucm0gPSBUUlVFKSwKICAgIGF2Z19lbmVyZ3lfbm9fc29sYXIgPSBtZWFuKGVsZWNfY29uc3VtcHRpb25fa3doW2hlYXRfbWV0aG9kICE9IDZdLCBuYS5ybSA9IFRSVUUpLAogICAgc29sYXJfaW1wYWN0ID0gYXZnX2VuZXJneV93aXRoX3NvbGFyIC0gYXZnX2VuZXJneV9ub19zb2xhciwKICAgIAogICAgYXZnX2VuZXJneV93aXRoX2VsZWNfaGVhdCA9IG1lYW4oZWxlY19jb25zdW1wdGlvbl9rd2hbaGVhdF9tZXRob2QgPT0gMl0sIG5hLnJtID0gVFJVRSksCiAgICBhdmdfZW5lcmd5X25vX2VsZWNfaGVhdCA9IG1lYW4oZWxlY19jb25zdW1wdGlvbl9rd2hbaGVhdF9tZXRob2QgIT0gMl0sIG5hLnJtID0gVFJVRSksCiAgICBlbGVjX2hlYXRfaW1wYWN0ID0gYXZnX2VuZXJneV93aXRoX2VsZWNfaGVhdCAtIGF2Z19lbmVyZ3lfbm9fZWxlY19oZWF0CiAgKQoKIyBGdW5jdGlvbiB0byBjYWxjdWxhdGUgZW5lcmd5IGltcGFjdApjYWxjdWxhdGVfZW5lcmd5X2ltcGFjdCA8LSBmdW5jdGlvbihjdXJyZW50X2Fkb3B0aW9uLCBmdXR1cmVfYWRvcHRpb24sIGVuZXJneV9pbXBhY3QsIGhvdXNlaG9sZHMgPSAxMDAwKSB7CiAgYWRkaXRpb25hbF9hZG9wdGVycyA9IChmdXR1cmVfYWRvcHRpb24gLSBjdXJyZW50X2Fkb3B0aW9uKSAqIGhvdXNlaG9sZHMgLyAxMDAKICB0b3RhbF9pbXBhY3QgPSBhZGRpdGlvbmFsX2Fkb3B0ZXJzICogZW5lcmd5X2ltcGFjdAogIHJldHVybih0b3RhbF9pbXBhY3QpCn0KCiMgQ2FsY3VsYXRlIGltcGFjdHMKdGVjaF9pbXBhY3RzIDwtIGxpc3QoKQppbXBhY3RfY291bnRlciA8LSAwCgpmb3IodGVjaCBpbiB0ZWNobm9sb2dpZXMpIHsKICBjYXQoIlxuUHJvY2Vzc2luZyBpbXBhY3RzIGZvciIsIHRlY2gsICJcbiIpCiAgCiAgZm9yKGQgaW4gMToxMCkgewogICAgY2F0KCIgIFByb2Nlc3NpbmcgZGVjaWxlIiwgZCwgIlxuIikKICAgIAogICAgaWYoIWlzLm51bGwoZm9yZWNhc3RzX2J5X2RlY2lsZVtbdGVjaF1dW1tkXV0pKSB7CiAgICAgIGZvcmVjYXN0IDwtIGZvcmVjYXN0c19ieV9kZWNpbGVbW3RlY2hdXVtbZF1dCiAgICAgIGN1cnJlbnQgPC0gY3VycmVudF9yYXRlc1tjdXJyZW50X3JhdGVzJGRlY2lsZSA9PSBkLCBdCiAgICAgIGJhc2VsaW5lIDwtIGJhc2VsaW5lX2NvbnN1bXB0aW9uW2Jhc2VsaW5lX2NvbnN1bXB0aW9uJGRlY2lsZSA9PSBkLCBdCiAgICAgIAogICAgICBpbXBhY3RfY291bnRlciA8LSBpbXBhY3RfY291bnRlciArIDEKICAgICAgdGVjaF9pbXBhY3RzW1tpbXBhY3RfY291bnRlcl1dIDwtIGRhdGEuZnJhbWUoCiAgICAgICAgdGVjaG5vbG9neSA9IGdzdWIoIl9wcm9wIiwgIiIsIHRlY2gpLAogICAgICAgIGRlY2lsZSA9IGQsCiAgICAgICAgYWRkaXRpb25hbF9lbmVyZ3lfMjAzMCA9IGNhbGN1bGF0ZV9lbmVyZ3lfaW1wYWN0KAogICAgICAgICAgY3VycmVudFtbcGFzdGUwKCJjdXJyZW50XyIsIGdzdWIoIl9wcm9wIiwgIiIsIHRlY2gpKV1dLCAKICAgICAgICAgIGZvcmVjYXN0JHByZWRpY3Rpb25zJHByZWRpY3RlZF9hZG9wdGlvbltmb3JlY2FzdCRwcmVkaWN0aW9ucyR5ZWFyID09IDIwMzBdLAogICAgICAgICAgc3dpdGNoKHRlY2gsCiAgICAgICAgICAgICAgICAiaHlicmlkX3Byb3AiID0gYmFzZWxpbmUkaHlicmlkX2ltcGFjdCwKICAgICAgICAgICAgICAgICJzb2xhcl9wcm9wIiA9IGJhc2VsaW5lJHNvbGFyX2ltcGFjdCwKICAgICAgICAgICAgICAgICJmdWVsX3N3aXRjaF9wcm9wIiA9IGJhc2VsaW5lJGVsZWNfaGVhdF9pbXBhY3QpCiAgICAgICAgKSwKICAgICAgICBhZGRpdGlvbmFsX2VuZXJneV8yMDQwID0gY2FsY3VsYXRlX2VuZXJneV9pbXBhY3QoCiAgICAgICAgICBjdXJyZW50W1twYXN0ZTAoImN1cnJlbnRfIiwgZ3N1YigiX3Byb3AiLCAiIiwgdGVjaCkpXV0sIAogICAgICAgICAgZm9yZWNhc3QkcHJlZGljdGlvbnMkcHJlZGljdGVkX2Fkb3B0aW9uW2ZvcmVjYXN0JHByZWRpY3Rpb25zJHllYXIgPT0gMjA0MF0sCiAgICAgICAgICBzd2l0Y2godGVjaCwKICAgICAgICAgICAgICAgICJoeWJyaWRfcHJvcCIgPSBiYXNlbGluZSRoeWJyaWRfaW1wYWN0LAogICAgICAgICAgICAgICAgInNvbGFyX3Byb3AiID0gYmFzZWxpbmUkc29sYXJfaW1wYWN0LAogICAgICAgICAgICAgICAgImZ1ZWxfc3dpdGNoX3Byb3AiID0gYmFzZWxpbmUkZWxlY19oZWF0X2ltcGFjdCkKICAgICAgICApLAogICAgICAgIGFkZGl0aW9uYWxfZW5lcmd5XzIwNTAgPSBjYWxjdWxhdGVfZW5lcmd5X2ltcGFjdCgKICAgICAgICAgIGN1cnJlbnRbW3Bhc3RlMCgiY3VycmVudF8iLCBnc3ViKCJfcHJvcCIsICIiLCB0ZWNoKSldXSwgCiAgICAgICAgICBmb3JlY2FzdCRwcmVkaWN0aW9ucyRwcmVkaWN0ZWRfYWRvcHRpb25bZm9yZWNhc3QkcHJlZGljdGlvbnMkeWVhciA9PSAyMDUwXSwKICAgICAgICAgIHN3aXRjaCh0ZWNoLAogICAgICAgICAgICAgICAgImh5YnJpZF9wcm9wIiA9IGJhc2VsaW5lJGh5YnJpZF9pbXBhY3QsCiAgICAgICAgICAgICAgICAic29sYXJfcHJvcCIgPSBiYXNlbGluZSRzb2xhcl9pbXBhY3QsCiAgICAgICAgICAgICAgICAiZnVlbF9zd2l0Y2hfcHJvcCIgPSBiYXNlbGluZSRlbGVjX2hlYXRfaW1wYWN0KQogICAgICAgICkKICAgICAgKQogICAgfQogIH0KfQoKIyBDb21iaW5lIHJlc3VsdHMgaWYgd2UgaGF2ZSBhbnkKaWYobGVuZ3RoKHRlY2hfaW1wYWN0cykgPiAwKSB7CiAgdGVjaF9pbXBhY3RzX2RmIDwtIGRvLmNhbGwocmJpbmQsIHRlY2hfaW1wYWN0cykKICAKICAjIENyZWF0ZSB2aXN1YWxpemF0aW9uCiAgZ2dwbG90KHRlY2hfaW1wYWN0c19kZiAlPiUgCiAgICAgICAgICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBzdGFydHNfd2l0aCgiYWRkaXRpb25hbF9lbmVyZ3kiKSwKICAgICAgICAgICAgICAgICAgICAgICBuYW1lc190byA9ICJ5ZWFyIiwKICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiZW5lcmd5X2ltcGFjdCIpICU+JQogICAgICAgICAgIG11dGF0ZSh5ZWFyID0gYXMubnVtZXJpYyhnc3ViKCJhZGRpdGlvbmFsX2VuZXJneV8iLCAiIiwgeWVhcikpKSwgCiAgICAgICAgIGFlcyh4ID0gZmFjdG9yKGRlY2lsZSksIHkgPSBlbmVyZ3lfaW1wYWN0LCBmaWxsID0gdGVjaG5vbG9neSkpICsKICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKwogICAgZmFjZXRfd3JhcCh+eWVhcikgKwogICAgdGhlbWVfbWluaW1hbCgpICsKICAgIGxhYnMoCiAgICAgIHRpdGxlID0gIlByb2plY3RlZCBBZGRpdGlvbmFsIEVuZXJneSBEZW1hbmQgZnJvbSBUZWNobm9sb2d5IEFkb3B0aW9uIiwKICAgICAgc3VidGl0bGUgPSAiQnkgaW5jb21lIGRlY2lsZSBhbmQgdGVjaG5vbG9neSB0eXBlIiwKICAgICAgeCA9ICJJbmNvbWUgRGVjaWxlIiwKICAgICAgeSA9ICJBZGRpdGlvbmFsIEFubnVhbCBFbmVyZ3kgQ29uc3VtcHRpb24gKGtXaCkiLAogICAgICBmaWxsID0gIlRlY2hub2xvZ3kiCiAgICApICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQogIAogICMgUHJpbnQgc3VtbWFyeSBzdGF0aXN0aWNzCiAgY2F0KCJcblN1bW1hcnkgb2YgQWRkaXRpb25hbCBFbmVyZ3kgRGVtYW5kIChrV2gpOlxuIikKICBwcmludCh0ZWNoX2ltcGFjdHNfZGYgJT4lCiAgICAgICAgICBncm91cF9ieSh0ZWNobm9sb2d5KSAlPiUKICAgICAgICAgIHN1bW1hcmlzZSgKICAgICAgICAgICAgdG90YWxfMjAzMCA9IHN1bShhZGRpdGlvbmFsX2VuZXJneV8yMDMwLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICB0b3RhbF8yMDQwID0gc3VtKGFkZGl0aW9uYWxfZW5lcmd5XzIwNDAsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIHRvdGFsXzIwNTAgPSBzdW0oYWRkaXRpb25hbF9lbmVyZ3lfMjA1MCwgbmEucm0gPSBUUlVFKQogICAgICAgICAgKSkKfQpgYGAK